<commit_before>package method

import "github.com/qlova/ilang/src"
import "github.com/qlova/ilang/src/modules/function"

var Flag = ilang.NewFlag()
var New = ilang.NewFlag()

func init() {
	ilang.RegisterToken([]string{"method"}, ScanMethod)
	ilang.RegisterListener(New, NewEnd)

	ilang.RegisterDefault(func(ic *ilang.Compiler) bool {
		token := ic.LastToken
		if ic.GetFlag(Flag) {
			if _, ok := ic.LastDefinedType.Detail.Table[token]; ok {
				ic.NextToken = ic.LastDefinedType.Name
				ic.NextNextToken = "."
				ic.NextNextNextToken = token
				ic.ScanStatement()
				return true
			}
		}
		return false
	})

	ilang.RegisterExpression(func(ic *ilang.Compiler) string {
		token := ic.LastToken
		if ic.GetFlag(Flag) {
			if ic.TypeExists(token) && ic.LastDefinedType.Super == token {
	 			ic.ExpressionType = ic.DefinedTypes[ic.LastDefinedType.Super]
				return ic.Shunt(ic.LastDefinedType.Name)
		 	}

			//Scope methods with multiple arguments inside the method.
			//eg. method Package.dosomething(22)
			// in a Package method, dosomething(22) should be local.
			if _, ok  := ic.DefinedFunctions[token+"_m_"+ic.LastDefinedType.Name]; ok {
				var f = token+"_m_"+ic.LastDefinedType.Name

				if !ic.LastDefinedType.Empty() {
					ic.Assembly(ic.LastDefinedType.Push," ", ic.LastDefinedType.Name)
				}

				ic.ExpressionType = function.Flag

				return ic.Shunt(f)
			}
		}

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {
				ic.Scan('.')
				ic.ExpressionType = function.Flag
				var name = ic.Scan(ilang.Name)
				return name+"_m_"+token
			}
		}

	 	return ""
	})

	ilang.RegisterVariable(func(ic *ilang.Compiler, name string) ilang.Type {
		//Allow table values to be indexed in a method.
		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[name]; ok {
				ic.DisableOwnership = true
				var value = ic.IndexUserType(ic.LastDefinedType.Name, name)
				ic.DisableOwnership = false

				ic.AssembleVar(name, value)
				ic.SetVariable(name+"_use", ilang.Used)
				return ic.ExpressionType
			}
		}
		return ilang.Undefined
	})

	ilang.RegisterShunt(".", ShuntMethodCall)
}

func Sync(ic *ilang.Compiler, variables ...string) {
	if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {

		for _, variable := range variables {

			if _, ok := ic.LastDefinedType.Detail.Table[variable]; ok {
				ic.SetUserType(ic.LastDefinedType.Name, variable, variable)
			}
		}
	}
}

func ShuntMethodCall(ic *ilang.Compiler, name string) string {
	var index = ic.Scan(ilang.Name)

	if f, ok  := ic.DefinedFunctions[index+"_m_"+ic.ExpressionType.GetComplexName()]; ok && len(f.Args) > 0 {
		var f = index+"_m_"+ic.ExpressionType.GetComplexName()
		ic.Assembly(ic.ExpressionType.Push," ", name)
		ic.ExpressionType = function.Flag
		return ic.Shunt(f)
	}

	ic.NextToken = index
	return ""
}

func NewEnd(ic *ilang.Compiler) {
	ic.Assembly("SHARE ", ic.LastDefinedType.Name)
	ic.LoseScope()
}

func Call(ic *ilang.Compiler, name string, t ilang.Type) {
	ic.Assembly(ic.RunFunction(name+"_m_"+t.GetComplexName()))
}

func ScanMethod(ic *ilang.Compiler) {
	ic.Header = false

	var name string = ic.Scan(ilang.Name)

	f := ic.DefinedFunctions[name]
	f.Method = true
	ic.DefinedFunctions[name] = f

	/*if name == "new" {
		ic.Scan('(')
		ic.ScanNew()
		return
	}*/

	var MethodType = ic.LastDefinedType

	var token = ic.Scan(0)
	if token == "(" {
		token = ic.Scan(0)
		if token != ")" {
			if t, ok := ic.DefinedTypes[token]; ok {
				MethodType = t
			} else {
				ic.NextToken = token
			}
		}

		ic.LastDefinedType = MethodType

		if MethodType.Name == "Game" && name == "new" {
			ic.NewGame = true
		}
		if MethodType.Name == "Game" && name == "draw" {
			ic.DrawGame = true
		}
		if MethodType.Name == "Game" && name == "update" {
			ic.UpdateGame = true
		}

		name += "_m_"+MethodType.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()

		if name == "new_m_"+MethodType.Name {

			ic.Assembly("PUSH ", len(MethodType.Detail.Elements))
			ic.Assembly("MAKE")
			ic.Assembly("GRAB ", MethodType.Name)

			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)

		} else if  MethodType.Detail != nil && len(MethodType.Detail.Elements) > 0 {
			ic.Assembly("%v %v", MethodType.Pop, MethodType.Name)
			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)
		}

		function.CreateFromArguments(name, ic)
		ic.SetFlag(Flag)

		f = ic.DefinedFunctions[name]
		if name == "new_m_"+MethodType.Name {
			ic.GainScope()
			ic.SetFlag(New)
			f.Returns = []ilang.Type{MethodType}

		}

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	//Functional methods.
	} else if token == "." {

		if !ic.TypeExists(name) {
			ic.RaiseError("Undefined type: ", name)
		}

		t := ic.DefinedTypes[name]
		ic.LastDefinedType = t

		name = ic.Scan(ilang.Name)
		name += "_m_"+t.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()
		ic.Scan('(')

		function.CreateFromArguments(name, ic)

		if len(t.Detail.Elements) > 0 {
			ic.Assembly("%v %v", t.Pop, t.Name)
			ic.SetVariable(t.Name, t)
			ic.SetVariable(t.Name+"_use", ilang.Used)
		}

		f = ic.DefinedFunctions[name]
		ic.SetFlag(Flag)

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	} else {
		var symbol = token
		var other = ic.Scan(ilang.Name)
		ic.Scan('{')

		if t, ok := ic.DefinedTypes[name]; ok {
			MethodType = t
		}

		var a = MethodType

		MethodType = ic.DefinedTypes[other]

		ic.LastDefinedType = MethodType

		var b = MethodType

		ilang.NewOperator(a, symbol, b, "SHARE %a\n SHARE %b\nRUN "+a.Name+"_"+symbol+"_"+b.Name+"\nGRAB %c", true)

		ic.Assembly("FUNCTION %s_%s_%s\n", a.Name, symbol, b.Name)
		ic.GainScope()
		ic.Assembly("GRAB b\nGRAB a\nARRAY c\n")
		for range a.Detail.Elements {
			ic.Assembly("PUT 0\n")
		}
		ic.InOperatorFunction = true

		ic.SetFlag(function.Flag)

		ic.SetVariable("c", a)
		ic.SetVariable("a", a)
		ic.SetVariable("b", b)
	}
}

<commit_msg>Fix multi-argument methods.<commit_after>package method

import "github.com/qlova/ilang/src"
import "github.com/qlova/ilang/src/modules/function"

var Flag = ilang.NewFlag()
var New = ilang.NewFlag()

func init() {
	ilang.RegisterToken([]string{"method"}, ScanMethod)
	ilang.RegisterListener(New, NewEnd)

	ilang.RegisterDefault(func(ic *ilang.Compiler) bool {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {
				ic.Scan('.')
				ic.ExpressionType = function.Flag
				var name = ic.Scan(ilang.Name)
				ic.Shunt(name+"_m_"+token)
				ic.Scan('(') //BUG I don't know why this has to be here.
				return true
			}
		}

		if ic.GetFlag(Flag) {
			if _, ok := ic.LastDefinedType.Detail.Table[token]; ok {
				ic.NextToken = ic.LastDefinedType.Name
				ic.NextNextToken = "."
				ic.NextNextNextToken = token
				ic.ScanStatement()
				return true
			}
		}

		return false
	})

	ilang.RegisterExpression(func(ic *ilang.Compiler) string {
		token := ic.LastToken

		if ic.TypeExists(token) {
			if ic.DefinedTypes[token].Empty() && ic.Peek() == "." {
				ic.Scan('.')
				ic.ExpressionType = function.Flag
				var name = ic.Scan(ilang.Name)
				return name+"_m_"+token
			}
		}

		if ic.GetFlag(Flag) {
			if ic.TypeExists(token) && ic.LastDefinedType.Super == token {
	 			ic.ExpressionType = ic.DefinedTypes[ic.LastDefinedType.Super]
				return ic.Shunt(ic.LastDefinedType.Name)
		 	}

			//Scope methods with multiple arguments inside the method.
			//eg. method Package.dosomething(22)
			// in a Package method, dosomething(22) should be local.
			if _, ok  := ic.DefinedFunctions[token+"_m_"+ic.LastDefinedType.Name]; ok {
				var f = token+"_m_"+ic.LastDefinedType.Name

				if !ic.LastDefinedType.Empty() {
					ic.Assembly(ic.LastDefinedType.Push," ", ic.LastDefinedType.Name)
				}

				ic.ExpressionType = function.Flag

				return ic.Shunt(f)
			}
		}

	 	return ""
	})

	ilang.RegisterVariable(func(ic *ilang.Compiler, name string) ilang.Type {
		//Allow table values to be indexed in a method.
		if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {
			if _, ok := ic.LastDefinedType.Detail.Table[name]; ok {
				ic.DisableOwnership = true
				var value = ic.IndexUserType(ic.LastDefinedType.Name, name)
				ic.DisableOwnership = false

				ic.AssembleVar(name, value)
				ic.SetVariable(name+"_use", ilang.Used)
				return ic.ExpressionType
			}
		}
		return ilang.Undefined
	})

	ilang.RegisterShunt(".", ShuntMethodCall)
}

func Sync(ic *ilang.Compiler, variables ...string) {
	if ic.GetFlag(Flag) && ic.LastDefinedType.Detail != nil {

		for _, variable := range variables {

			if _, ok := ic.LastDefinedType.Detail.Table[variable]; ok {
				ic.SetUserType(ic.LastDefinedType.Name, variable, variable)
			}
		}
	}
}

func ShuntMethodCall(ic *ilang.Compiler, name string) string {
	var index = ic.Scan(ilang.Name)

	if f, ok  := ic.DefinedFunctions[index+"_m_"+ic.ExpressionType.GetComplexName()]; ok && len(f.Args) > 0 {
		var f = index+"_m_"+ic.ExpressionType.GetComplexName()
		ic.Assembly(ic.ExpressionType.Push," ", name)
		ic.ExpressionType = function.Flag
		return ic.Shunt(f)
	}

	ic.NextToken = index
	return ""
}

func NewEnd(ic *ilang.Compiler) {
	ic.Assembly("SHARE ", ic.LastDefinedType.Name)
	ic.LoseScope()
}

func Call(ic *ilang.Compiler, name string, t ilang.Type) {
	ic.Assembly(ic.RunFunction(name+"_m_"+t.GetComplexName()))
}

func ScanMethod(ic *ilang.Compiler) {
	ic.Header = false

	var name string = ic.Scan(ilang.Name)

	f := ic.DefinedFunctions[name]
	f.Method = true
	ic.DefinedFunctions[name] = f

	/*if name == "new" {
		ic.Scan('(')
		ic.ScanNew()
		return
	}*/

	var MethodType = ic.LastDefinedType

	var token = ic.Scan(0)
	if token == "(" {
		token = ic.Scan(0)
		if token != ")" {
			if t, ok := ic.DefinedTypes[token]; ok {
				MethodType = t
			} else {
				ic.NextToken = token
			}
		}

		ic.LastDefinedType = MethodType

		if MethodType.Name == "Game" && name == "new" {
			ic.NewGame = true
		}
		if MethodType.Name == "Game" && name == "draw" {
			ic.DrawGame = true
		}
		if MethodType.Name == "Game" && name == "update" {
			ic.UpdateGame = true
		}

		name += "_m_"+MethodType.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()

		if name == "new_m_"+MethodType.Name {

			ic.Assembly("PUSH ", len(MethodType.Detail.Elements))
			ic.Assembly("MAKE")
			ic.Assembly("GRAB ", MethodType.Name)

			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)

		} else if  MethodType.Detail != nil && len(MethodType.Detail.Elements) > 0 {
			ic.Assembly("%v %v", MethodType.Pop, MethodType.Name)
			ic.SetVariable(MethodType.Name, MethodType)
			ic.SetVariable(MethodType.Name+"_use", ilang.Used)
			ic.SetVariable(MethodType.Name+".", ilang.Protected)
		}

		function.CreateFromArguments(name, ic)
		ic.SetFlag(Flag)

		f = ic.DefinedFunctions[name]
		if name == "new_m_"+MethodType.Name {
			ic.GainScope()
			ic.SetFlag(New)
			f.Returns = []ilang.Type{MethodType}

		}

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	//Functional methods.
	} else if token == "." {

		if !ic.TypeExists(name) {
			ic.RaiseError("Undefined type: ", name)
		}

		t := ic.DefinedTypes[name]
		ic.LastDefinedType = t

		name = ic.Scan(ilang.Name)
		name += "_m_"+t.Name

		ic.Assembly("FUNCTION ", name)
		ic.GainScope()
		ic.Scan('(')

		function.CreateFromArguments(name, ic)

		if len(t.Detail.Elements) > 0 {
			ic.Assembly("%v %v", t.Pop, t.Name)
			ic.SetVariable(t.Name, t)
			ic.SetVariable(t.Name+"_use", ilang.Used)
		}

		f = ic.DefinedFunctions[name]
		ic.SetFlag(Flag)

		f.Method = true
		ic.DefinedFunctions[name] = f

		ic.InsertPlugins(name)

	} else {
		var symbol = token
		var other = ic.Scan(ilang.Name)
		ic.Scan('{')

		if t, ok := ic.DefinedTypes[name]; ok {
			MethodType = t
		}

		var a = MethodType

		MethodType = ic.DefinedTypes[other]

		ic.LastDefinedType = MethodType

		var b = MethodType

		ilang.NewOperator(a, symbol, b, "SHARE %a\n SHARE %b\nRUN "+a.Name+"_"+symbol+"_"+b.Name+"\nGRAB %c", true)

		ic.Assembly("FUNCTION %s_%s_%s\n", a.Name, symbol, b.Name)
		ic.GainScope()
		ic.Assembly("GRAB b\nGRAB a\nARRAY c\n")
		for range a.Detail.Elements {
			ic.Assembly("PUT 0\n")
		}
		ic.InOperatorFunction = true

		ic.SetFlag(function.Flag)

		ic.SetVariable("c", a)
		ic.SetVariable("a", a)
		ic.SetVariable("b", b)
	}
}

<|endoftext|>


<commit_before>package database

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
    "mud/utils"
    //"fmt"
)

type dbError struct {
	message string
}

func (self dbError) Error() string {
	return self.message
}

func newDbError(message string) dbError {
	var err dbError
	err.message = message
	return err
}

type collectionName string

func getCollection(session *mgo.Session, collection collectionName) *mgo.Collection {
	return session.DB("mud").C(string(collection))
}

const (
    cUsers = collectionName("users")
    cCharacters = collectionName("characters")
)

func FindUser(session *mgo.Session, name string) (bool, error) {
	c := getCollection(session, cUsers)
	q := c.Find(bson.M{"name": name})

	count, err := q.Count()

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

func FindCharacter(session *mgo.Session, name string) (bool, error) {
	c := getCollection(session, cCharacters)
	q := c.Find(bson.M{"name": name})

	count, err := q.Count()

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

func NewUser(session *mgo.Session, name string) error {

	found, err := FindUser(session, name)

	if err != nil {
		return err
	}

	if found {
		return newDbError("That user already exists")
	}

	c := getCollection(session, cUsers)
	c.Insert(bson.M{"name": name})

	return nil
}

func NewCharacter(session *mgo.Session, user string, character string) error {

    found, err := FindCharacter(session, character)

    if err != nil {
        return err
    }

    if found {
        return newDbError("That character already exists")
    }

	c := getCollection(session, cUsers)
	c.Update(bson.M{"name": user}, bson.M{"$push": bson.M{"characters": character}})

    c = getCollection(session, cCharacters)
    c.Insert(bson.M{"name": character})

	return nil
}

func GetCharacterLocation(session *mgo.Session, name string) (string, error) {
	c := getCollection(session, cCharacters)
	q := c.Find(bson.M{"name": name})

	result := map[string]string{}
	err := q.One(&result)

	if err != nil {
		return "", err
	}

	return result["location"], nil
}

func SetUserLocation(session *mgo.Session, name string, locationId string) error {
	c := getCollection(session, cUsers)
	c.Update(bson.M{"name": name}, bson.M{"location": locationId})
	return nil
}

func GetUserCharacters(session *mgo.Session, name string) ([]string, error) {
	c := getCollection(session, cUsers)
	q := c.Find(bson.M{"name": name})

	result := map[string][]string{}
	err := q.One(&result)

	return result["characters"], err
}

func DeleteCharacter(session *mgo.Session, user string, character string) error {
	c := getCollection(session, cUsers)
	c.Update(bson.M{"name": user}, bson.M{"$pull": bson.M{"characters": utils.Simplify(character)}})

    c = getCollection(session, cCharacters)
    c.Remove(bson.M{"name": character})

	return nil
}

// vim: nocindent
<commit_msg>More magic strings<commit_after>package database

import (
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
    "mud/utils"
    //"fmt"
)

type dbError struct {
	message string
}

func (self dbError) Error() string {
	return self.message
}

func newDbError(message string) dbError {
	var err dbError
	err.message = message
	return err
}

type collectionName string

func getCollection(session *mgo.Session, collection collectionName) *mgo.Collection {
	return session.DB("mud").C(string(collection))
}

// Collection names
const (
    cUsers = collectionName("users")
    cCharacters = collectionName("characters")
)

// Field names
const (
    fName = "name"
    fCharacters = "characters"
)

func FindUser(session *mgo.Session, name string) (bool, error) {
	c := getCollection(session, cUsers)
	q := c.Find(bson.M{fName: name})

	count, err := q.Count()

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

func FindCharacter(session *mgo.Session, name string) (bool, error) {
	c := getCollection(session, cCharacters)
	q := c.Find(bson.M{fName: name})

	count, err := q.Count()

	if err != nil {
		return false, err
	}

	return count > 0, nil
}

func NewUser(session *mgo.Session, name string) error {

	found, err := FindUser(session, name)

	if err != nil {
		return err
	}

	if found {
		return newDbError("That user already exists")
	}

	c := getCollection(session, cUsers)
	c.Insert(bson.M{fName: name})

	return nil
}

func NewCharacter(session *mgo.Session, user string, character string) error {

    found, err := FindCharacter(session, character)

    if err != nil {
        return err
    }

    if found {
        return newDbError("That character already exists")
    }

	c := getCollection(session, cUsers)
	c.Update(bson.M{fName: user}, bson.M{"$push": bson.M{fCharacters: character}})

    c = getCollection(session, cCharacters)
    c.Insert(bson.M{fName: character})

	return nil
}

func GetCharacterLocation(session *mgo.Session, name string) (string, error) {
	c := getCollection(session, cCharacters)
	q := c.Find(bson.M{fName: name})

	result := map[string]string{}
	err := q.One(&result)

	if err != nil {
		return "", err
	}

	return result["location"], nil
}

func SetUserLocation(session *mgo.Session, name string, locationId string) error {
	c := getCollection(session, cUsers)
	c.Update(bson.M{fName: name}, bson.M{"location": locationId})
	return nil
}

func GetUserCharacters(session *mgo.Session, name string) ([]string, error) {
	c := getCollection(session, cUsers)
	q := c.Find(bson.M{fName: name})

	result := map[string][]string{}
	err := q.One(&result)

	return result[fCharacters], err
}

func DeleteCharacter(session *mgo.Session, user string, character string) error {
	c := getCollection(session, cUsers)
	c.Update(bson.M{fName: user}, bson.M{"$pull": bson.M{fCharacters: utils.Simplify(character)}})

    c = getCollection(session, cCharacters)
    c.Remove(bson.M{fName: character})

	return nil
}

// vim: nocindent
<|endoftext|>


<commit_before>// Licensed to Elasticsearch B.V. under one or more agreements.
// Elasticsearch B.V. licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

package gensource

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"unicode"

	"gopkg.in/yaml.v2"

	"github.com/elastic/go-elasticsearch/v8/internal/cmd/generate/utils"
)

var (
	apiDescriptions map[interface{}]interface{}
)

func init() {
	err := yaml.NewDecoder(strings.NewReader(apiDescriptionsYAML)).Decode(&apiDescriptions)
	if err != nil {
		panic(fmt.Sprintf("ERROR: %v", err))
	}
}

// NewEndpoint creates a new API endpoint.
//
func NewEndpoint(f io.Reader) (*Endpoint, error) {
	var endpoint Endpoint
	var spec map[string]Endpoint

	if err := json.NewDecoder(f).Decode(&spec); err != nil {
		return nil, err
	}

	for name, e := range spec {
		endpoint = e
		endpoint.Name = name
		endpoint.URL.Params = endpoint.Params
	}

	if fpath, ok := f.(*os.File); ok {
		if strings.Contains(fpath.Name(), "x-pack") {
			endpoint.Type = "xpack"
		}
	}
	if endpoint.Type == "" {
		endpoint.Type = "core"
	}

	endpoint.URL.AllParts = make(map[string]*Part)

	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			part.Endpoint = &endpoint
			part.Name = partName
		}
	}

	var params [][]string
	for _, path := range endpoint.URL.Paths {
		var parts []string
		for partName := range path.Parts {
			parts = append(parts, partName)
		}
		params = append(params, parts)
	}

	var paramsCounter = make(map[string]int)
	for _, pp := range params {
		for _, p := range pp {
			paramsCounter[p] += 1
		}
	}

	// Update the required field of path parts
	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			if p, ok := paramsCounter[partName]; ok {
				if p == len(params) {
					part.Required = true
				}
			}
		}
	}

	for paramName, p := range endpoint.URL.Params {
		p.Endpoint = &endpoint
		p.Name = paramName
	}

	// Update the AllParts field
	var partSeen = make(map[string]bool)
	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			if !partSeen[partName] {
				endpoint.URL.AllParts[partName] = part
			}
			partSeen[partName] = true
		}
	}

	// Fix up the documentation property (X-Pack spec related); TODO: PR
	if !strings.HasPrefix(endpoint.Documentation.URL, "http") {
		if endpoint.Type == "xpack" && endpoint.Documentation.Description == "" && endpoint.Documentation.URL != "" {
			endpoint.Documentation.Description = endpoint.Documentation.URL
		}
		endpoint.Documentation.URL = ""
	}

	var partNames []string
	for param := range paramsCounter {
		partNames = append(partNames, param)
	}
	sort.Slice(partNames, func(i, j int) bool {
		return strings.Replace(partNames[i], "_", "", 1) < strings.Replace(partNames[j], "_", "", 1)
	})
	endpoint.URL.PartNamesSorted = partNames

	var paramNames []string
	for _, param := range endpoint.URL.Params {
		paramNames = append(paramNames, param.Name)
	}
	sort.Slice(paramNames, func(i, j int) bool {
		return strings.Replace(paramNames[i], "_", "", 1) < strings.Replace(paramNames[j], "_", "", 1)
	})
	endpoint.URL.ParamNamesSorted = paramNames

	for _, path := range endpoint.URL.Paths {
		for _, part := range path.Parts {
			if part.Name == "type" {
				part.Default = "_doc"
			}
		}
	}

	// if info, ok := apiDescriptions[endpoint.Name]; ok {
	// 	if desc, ok := info.(map[interface{}]interface{})["description"].(string); ok {
	// 		endpoint.Documentation.Description = desc
	// 	}
	// }

	return &endpoint, nil
}

// Endpoint represents an API endpoint.
//
type Endpoint struct {
	Name string `json:"-"`
	Type string `json:"-"`

	Documentation struct {
		URL         string `json:"url"`
		Description string `json:"description"`
	} `json:"documentation"`

	URL    *URL              `json:"url"`
	Params map[string]*Param `json:"params"`
	Body   *Body             `json:"body"`
}

// URL represents API endpoint URL.
//
type URL struct {
	Endpoint *Endpoint `json:"-"`

	Paths           []Path `json:"paths"`
	DeprecatedPaths []struct {
		Path        string `json:"path"`
		Version     string `json:"version"`
		Description string `json:"description"`
	} `json:"deprecated_paths"`
	Params map[string]*Param `json:"params"`

	AllParts         map[string]*Part
	PartNamesSorted  []string
	ParamNamesSorted []string
}

// Path represents URL path
type Path struct {
	Path       string           `json:"path"`
	Methods    []string         `json:"methods"`
	Parts      map[string]*Part `json:"parts"`
	Deprecated struct {
		Version     string `json:"version"`
		Description string `json:"description"`
	}
}

// Part represents part of the API endpoint URL.
//
type Part struct {
	Endpoint *Endpoint `json:"-"`

	Name    string      `json:"-"`
	Default interface{} `json:"-"`

	Type        string `json:"type"`
	Description string `json:"description"`
	Required    bool   `json:"required"`
}

// Param represents API endpoint parameter.
//
type Param struct {
	Endpoint *Endpoint `json:"-"`

	Name string `json:"-"`

	Type        string      `json:"type"`
	Description string      `json:"description"`
	Options     []string    `json:"options"`
	Default     interface{} `json:"default"`
	Required    bool        `json:"required"`
}

// Body represents API endpoint body.
//
type Body struct {
	Endpoint *Endpoint `json:"-"`

	Description string `json:"description"`
	Required    bool   `json:"required"`
	ContentType string `json:"serialize"`
}

// MethodArgument represents a method argument for API endpoint.
//
type MethodArgument struct {
	Endpoint *Endpoint

	Name        string
	Type        string
	Description string
	Options     []string
	Default     interface{}
	Required    bool
}

// Namespace returns the API endpoint namespace.
//
func (e *Endpoint) Namespace() string {
	ep := strings.Split(e.Name, ".")
	return utils.NameToGo(ep[0])
}

// MethodName returns the API endpoint method name.
//
func (e *Endpoint) MethodName() string {
	ep := strings.Split(e.Name, ".")
	ep = append(ep[:0], ep[1:]...)
	ns := make([]string, len(ep))
	for _, v := range ep {
		m := strings.Split(v, "_")
		mn := make([]string, len(m))
		for _, vv := range m {
			mn = append(mn, strings.Title(vv))
		}
		ns = append(ns, strings.Join(mn, ""))
	}
	return strings.Join(ns, "")
}

// MethodWithNamespace returns the API endpoint method name with namespace.
//
func (e *Endpoint) MethodWithNamespace() string {
	return utils.APIToGo(e.Name)
}

// HumanMethodWithNamespace returns the API endpoint method name in humanized form.
//
func (e *Endpoint) HumanMethodWithNamespace() string {
	var (
		src = e.MethodWithNamespace()
		out string
	)
	for i, l := range src {
		if unicode.IsUpper(l) && i > 0 {
			if i+2 <= len(src) && unicode.IsUpper([]rune(src[i+1 : i+2])[0]) {
				out += string(l)
			} else {
				out += " " + string(l)
			}
		} else {
			out += string(l)
		}
	}
	return out
}

// RequiredArguments return the list of required method arguments.
//
func (e *Endpoint) RequiredArguments() []MethodArgument {
	var args = make([]MethodArgument, 0)
	var prominentArgs = []string{
		"index",
		"type",
		"id",
		"repository",
		"snapshot",
		"snapshot_id",
		"calendar_id",
		"job_id",
		"username",
		"name",
	}

	var contains = func(s string) bool {
		for _, v := range args {
			if v.Name == s {
				return true
			}
		}
		return false
	}

	// Return the prominent arguments first
	for _, d := range prominentArgs {
		for _, p := range e.URL.Paths[0].Parts {
			if p.Name != d {
				continue
			}
			if p.Required {
				args = append(args, MethodArgument{
					Endpoint:    e,
					Name:        p.Name,
					Type:        p.Type,
					Description: p.Description,
					Required:    true,
				})
			}
			// Make the 'type' required for selected APIs
			if p.Name == "type" && (e.Name == "index" || e.Name == "create") {
				args = append(args, MethodArgument{
					Endpoint:    e,
					Name:        p.Name,
					Type:        p.Type,
					Description: p.Description,
					Required:    true,
				})
			}
		}
	}

	// Return the body after prominent arguments
	if e.Body != nil && e.Body.Required {
		args = append(args, MethodArgument{
			Endpoint:    e,
			Name:        "body",
			Description: e.Body.Description,
		})
	}

	// Return rest of the URL parts
	for _, p := range e.URL.Paths[0].Parts {
		if contains(p.Name) {
			continue
		}
		if p.Required {
			args = append(args, MethodArgument{
				Endpoint:    e,
				Name:        p.Name,
				Type:        p.Type,
				Description: p.Description,
				Required:    true,
			})
		}
	}

	// Return URL params
	for _, p := range e.URL.Params {
		if contains(p.Name) {
			continue
		}
		if p.Required {
			args = append(args, MethodArgument{
				Endpoint:    e,
				Name:        p.Name,
				Type:        p.Type,
				Description: p.Description,
				Options:     p.Options,
				Default:     p.Default,
				Required:    p.Required,
			})
		}
	}

	return args
}

// GoName returns a Go name for part.
//
func (p *Part) GoName() string {
	switch {
	case p.Name == "context":
		return "ScriptContext"
	default:
		return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
	}
}

// GoType returns a Go type for part.
//
func (p *Part) GoType(comment ...bool) string {
	return utils.TypeToGo(p.Type)
}

// GoName returns a Go name for parameter.
//
func (p *Param) GoName() string {
	switch {
	case p.Name == "context":
		return "ScriptContext"
	case p.Name == "q":
		return "Query"
	default:
		return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
	}
}

// GoType returns a Go type for parameter.
//
func (p *Param) GoType(comment ...bool) string {
	if f := (&Generator{Endpoint: p.Endpoint}).GetOverride("polymorphic-param", p.Endpoint.Name); f != nil {
		if out := f(p.Endpoint, p.Name); out != "" {
			return out
		}
	}
	return utils.TypeToGo(p.Type)
}

// GoName returns a Go name for method argument.
//
func (p *MethodArgument) GoName() string {
	return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
}

// GoType returns a Go type for method argument.
//
func (p *MethodArgument) GoType(comment ...bool) string {
	return utils.TypeToGo(p.Type)
}
<commit_msg>Generator: API: Remove the default for document type from model<commit_after>// Licensed to Elasticsearch B.V. under one or more agreements.
// Elasticsearch B.V. licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

package gensource

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"unicode"

	"gopkg.in/yaml.v2"

	"github.com/elastic/go-elasticsearch/v8/internal/cmd/generate/utils"
)

var (
	apiDescriptions map[interface{}]interface{}
)

func init() {
	err := yaml.NewDecoder(strings.NewReader(apiDescriptionsYAML)).Decode(&apiDescriptions)
	if err != nil {
		panic(fmt.Sprintf("ERROR: %v", err))
	}
}

// NewEndpoint creates a new API endpoint.
//
func NewEndpoint(f io.Reader) (*Endpoint, error) {
	var endpoint Endpoint
	var spec map[string]Endpoint

	if err := json.NewDecoder(f).Decode(&spec); err != nil {
		return nil, err
	}

	for name, e := range spec {
		endpoint = e
		endpoint.Name = name
		endpoint.URL.Params = endpoint.Params
	}

	if fpath, ok := f.(*os.File); ok {
		if strings.Contains(fpath.Name(), "x-pack") {
			endpoint.Type = "xpack"
		}
	}
	if endpoint.Type == "" {
		endpoint.Type = "core"
	}

	endpoint.URL.AllParts = make(map[string]*Part)

	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			part.Endpoint = &endpoint
			part.Name = partName
		}
	}

	var params [][]string
	for _, path := range endpoint.URL.Paths {
		var parts []string
		for partName := range path.Parts {
			parts = append(parts, partName)
		}
		params = append(params, parts)
	}

	var paramsCounter = make(map[string]int)
	for _, pp := range params {
		for _, p := range pp {
			paramsCounter[p] += 1
		}
	}

	// Update the required field of path parts
	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			if p, ok := paramsCounter[partName]; ok {
				if p == len(params) {
					part.Required = true
				}
			}
		}
	}

	for paramName, p := range endpoint.URL.Params {
		p.Endpoint = &endpoint
		p.Name = paramName
	}

	// Update the AllParts field
	var partSeen = make(map[string]bool)
	for _, path := range endpoint.URL.Paths {
		for partName, part := range path.Parts {
			if !partSeen[partName] {
				endpoint.URL.AllParts[partName] = part
			}
			partSeen[partName] = true
		}
	}

	// Fix up the documentation property (X-Pack spec related); TODO: PR
	if !strings.HasPrefix(endpoint.Documentation.URL, "http") {
		if endpoint.Type == "xpack" && endpoint.Documentation.Description == "" && endpoint.Documentation.URL != "" {
			endpoint.Documentation.Description = endpoint.Documentation.URL
		}
		endpoint.Documentation.URL = ""
	}

	var partNames []string
	for param := range paramsCounter {
		partNames = append(partNames, param)
	}
	sort.Slice(partNames, func(i, j int) bool {
		return strings.Replace(partNames[i], "_", "", 1) < strings.Replace(partNames[j], "_", "", 1)
	})
	endpoint.URL.PartNamesSorted = partNames

	var paramNames []string
	for _, param := range endpoint.URL.Params {
		paramNames = append(paramNames, param.Name)
	}
	sort.Slice(paramNames, func(i, j int) bool {
		return strings.Replace(paramNames[i], "_", "", 1) < strings.Replace(paramNames[j], "_", "", 1)
	})
	endpoint.URL.ParamNamesSorted = paramNames

	// if info, ok := apiDescriptions[endpoint.Name]; ok {
	// 	if desc, ok := info.(map[interface{}]interface{})["description"].(string); ok {
	// 		endpoint.Documentation.Description = desc
	// 	}
	// }

	return &endpoint, nil
}

// Endpoint represents an API endpoint.
//
type Endpoint struct {
	Name string `json:"-"`
	Type string `json:"-"`

	Documentation struct {
		URL         string `json:"url"`
		Description string `json:"description"`
	} `json:"documentation"`

	URL    *URL              `json:"url"`
	Params map[string]*Param `json:"params"`
	Body   *Body             `json:"body"`
}

// URL represents API endpoint URL.
//
type URL struct {
	Endpoint *Endpoint `json:"-"`

	Paths           []Path `json:"paths"`
	DeprecatedPaths []struct {
		Path        string `json:"path"`
		Version     string `json:"version"`
		Description string `json:"description"`
	} `json:"deprecated_paths"`
	Params map[string]*Param `json:"params"`

	AllParts         map[string]*Part
	PartNamesSorted  []string
	ParamNamesSorted []string
}

// Path represents URL path
type Path struct {
	Path       string           `json:"path"`
	Methods    []string         `json:"methods"`
	Parts      map[string]*Part `json:"parts"`
	Deprecated struct {
		Version     string `json:"version"`
		Description string `json:"description"`
	}
}

// Part represents part of the API endpoint URL.
//
type Part struct {
	Endpoint *Endpoint `json:"-"`

	Name    string      `json:"-"`
	Default interface{} `json:"-"`

	Type        string `json:"type"`
	Description string `json:"description"`
	Required    bool   `json:"required"`
}

// Param represents API endpoint parameter.
//
type Param struct {
	Endpoint *Endpoint `json:"-"`

	Name string `json:"-"`

	Type        string      `json:"type"`
	Description string      `json:"description"`
	Options     []string    `json:"options"`
	Default     interface{} `json:"default"`
	Required    bool        `json:"required"`
}

// Body represents API endpoint body.
//
type Body struct {
	Endpoint *Endpoint `json:"-"`

	Description string `json:"description"`
	Required    bool   `json:"required"`
	ContentType string `json:"serialize"`
}

// MethodArgument represents a method argument for API endpoint.
//
type MethodArgument struct {
	Endpoint *Endpoint

	Name        string
	Type        string
	Description string
	Options     []string
	Default     interface{}
	Required    bool
}

// Namespace returns the API endpoint namespace.
//
func (e *Endpoint) Namespace() string {
	ep := strings.Split(e.Name, ".")
	return utils.NameToGo(ep[0])
}

// MethodName returns the API endpoint method name.
//
func (e *Endpoint) MethodName() string {
	ep := strings.Split(e.Name, ".")
	ep = append(ep[:0], ep[1:]...)
	ns := make([]string, len(ep))
	for _, v := range ep {
		m := strings.Split(v, "_")
		mn := make([]string, len(m))
		for _, vv := range m {
			mn = append(mn, strings.Title(vv))
		}
		ns = append(ns, strings.Join(mn, ""))
	}
	return strings.Join(ns, "")
}

// MethodWithNamespace returns the API endpoint method name with namespace.
//
func (e *Endpoint) MethodWithNamespace() string {
	return utils.APIToGo(e.Name)
}

// HumanMethodWithNamespace returns the API endpoint method name in humanized form.
//
func (e *Endpoint) HumanMethodWithNamespace() string {
	var (
		src = e.MethodWithNamespace()
		out string
	)
	for i, l := range src {
		if unicode.IsUpper(l) && i > 0 {
			if i+2 <= len(src) && unicode.IsUpper([]rune(src[i+1 : i+2])[0]) {
				out += string(l)
			} else {
				out += " " + string(l)
			}
		} else {
			out += string(l)
		}
	}
	return out
}

// RequiredArguments return the list of required method arguments.
//
func (e *Endpoint) RequiredArguments() []MethodArgument {
	var args = make([]MethodArgument, 0)
	var prominentArgs = []string{
		"index",
		"type",
		"id",
		"repository",
		"snapshot",
		"snapshot_id",
		"calendar_id",
		"job_id",
		"username",
		"name",
	}

	var contains = func(s string) bool {
		for _, v := range args {
			if v.Name == s {
				return true
			}
		}
		return false
	}

	// Return the prominent arguments first
	for _, d := range prominentArgs {
		for _, p := range e.URL.Paths[0].Parts {
			if p.Name != d {
				continue
			}
			if p.Required {
				args = append(args, MethodArgument{
					Endpoint:    e,
					Name:        p.Name,
					Type:        p.Type,
					Description: p.Description,
					Required:    true,
				})
			}
			// Make the 'type' required for selected APIs
			if p.Name == "type" && (e.Name == "index" || e.Name == "create") {
				args = append(args, MethodArgument{
					Endpoint:    e,
					Name:        p.Name,
					Type:        p.Type,
					Description: p.Description,
					Required:    true,
				})
			}
		}
	}

	// Return the body after prominent arguments
	if e.Body != nil && e.Body.Required {
		args = append(args, MethodArgument{
			Endpoint:    e,
			Name:        "body",
			Description: e.Body.Description,
		})
	}

	// Return rest of the URL parts
	for _, p := range e.URL.Paths[0].Parts {
		if contains(p.Name) {
			continue
		}
		if p.Required {
			args = append(args, MethodArgument{
				Endpoint:    e,
				Name:        p.Name,
				Type:        p.Type,
				Description: p.Description,
				Required:    true,
			})
		}
	}

	// Return URL params
	for _, p := range e.URL.Params {
		if contains(p.Name) {
			continue
		}
		if p.Required {
			args = append(args, MethodArgument{
				Endpoint:    e,
				Name:        p.Name,
				Type:        p.Type,
				Description: p.Description,
				Options:     p.Options,
				Default:     p.Default,
				Required:    p.Required,
			})
		}
	}

	return args
}

// GoName returns a Go name for part.
//
func (p *Part) GoName() string {
	switch {
	case p.Name == "context":
		return "ScriptContext"
	default:
		return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
	}
}

// GoType returns a Go type for part.
//
func (p *Part) GoType(comment ...bool) string {
	return utils.TypeToGo(p.Type)
}

// GoName returns a Go name for parameter.
//
func (p *Param) GoName() string {
	switch {
	case p.Name == "context":
		return "ScriptContext"
	case p.Name == "q":
		return "Query"
	default:
		return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
	}
}

// GoType returns a Go type for parameter.
//
func (p *Param) GoType(comment ...bool) string {
	if f := (&Generator{Endpoint: p.Endpoint}).GetOverride("polymorphic-param", p.Endpoint.Name); f != nil {
		if out := f(p.Endpoint, p.Name); out != "" {
			return out
		}
	}
	return utils.TypeToGo(p.Type)
}

// GoName returns a Go name for method argument.
//
func (p *MethodArgument) GoName() string {
	return utils.NameToGo(p.Name, p.Endpoint.MethodWithNamespace())
}

// GoType returns a Go type for method argument.
//
func (p *MethodArgument) GoType(comment ...bool) string {
	return utils.TypeToGo(p.Type)
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	mongomodels "koding/db/models"
	"koding/db/mongodb/modelhelper"
	socialapimodels "socialapi/models"
	"strconv"
	"strings"
)

type Mail struct {
	FromName          string
	From              string
	OriginalRecipient string
	MailboxHash       string
	TextBody          string
	StrippedTextReply string
}

// errors
var (
	ErrNotValid          = errors.New("no valid content")
	ErrAccountIsNotFound = errors.New("Account is not found")
	ErrFromFieldIsNotSet = errors.New("From field is not set")
	ErrTextBodyIsNotSet  = errors.New("TextBody is not set")
	errInvalidMailPrefix = errors.New("invalid prefix")
)

// GetAccount gets the account which sent the message
func GetAccount(mailAddress string) (*mongomodels.Account, error) {
	user, err := modelhelper.FetchUserByEmail(mailAddress)
	if err != nil {
		return nil, err
	}

	account, err := modelhelper.GetAccount(user.Name)
	if err != nil {
		return nil, err
	}
	return account, nil
}

func (m *Mail) Validate() error {
	if m.From == "" {
		return ErrFromFieldIsNotSet
	}

	if m.TextBody == "" {
		return ErrTextBodyIsNotSet
	}

	return nil
}

// Examples of postmark inbound messages
// reply+messageid.1234@inbound.koding.com
// post+channelid.5678@inbound.koding.com
func (m *Mail) Persist() error {
	//acc := socialapimodels.NewAccount()
	acc, err := GetAccount(m.From)
	if err != nil {
		return errInvalidMailPrefix
	}

	accountId, err := acc.GetSocialApiId()
	if err != nil {
		return err
	}

	if strings.HasPrefix(m.OriginalRecipient, "post") {
		// Split method get the MailboxHash field
		// MailboxHash seems like "channelid.5678"
		s := strings.Split(m.MailboxHash, ".")
		// ParseInt get the 1. index (2.parameter) of "s" value
		// As explained above, we got 1. index that "5678" as string
		// and then, we convert string to int64
		cid, err := strconv.ParseInt(s[1], 10, 64)
		if err != nil {
			return err
		}

		channelId := cid
		c, err := socialapimodels.ChannelById(channelId)
		if err != nil {
			return err
		}

		cm := socialapimodels.NewChannelMessage()
		cm.Body = m.TextBody // set the body
		// todo set this type according to the the channel id
		cm.TypeConstant = socialapimodels.ChannelMessage_TYPE_POST
		cm.InitialChannelId = channelId
		cm.AccountId = accountId
		if err := cm.Create(); err != nil {
			return err
		}

		_, err = c.EnsureMessage(cm, true)
		if err != nil {
			return err
		}

		return nil
	}

	if strings.HasPrefix(m.OriginalRecipient, "reply") {
		s := strings.Split(m.MailboxHash, ".")
		mId, err := strconv.ParseInt(s[1], 10, 64)
		if err != nil {
			return err
		}
		messageId := mId
		cm, err := socialapimodels.ChannelMessageById(messageId)
		if err != nil {
			return err
		}

		// create reply
		reply := socialapimodels.NewChannelMessage()
		reply.Body = m.StrippedTextReply // set the body
		// todo set this type according to the the channel id
		reply.TypeConstant = socialapimodels.ChannelMessage_TYPE_REPLY
		reply.InitialChannelId = cm.InitialChannelId
		reply.AccountId = accountId
		if err := reply.Create(); err != nil {
			return err
		}

		if _, err = cm.AddReply(reply); err != nil {
			return err
		}
	}

	return errInvalidMailPrefix
}
<commit_msg>socialapi/mailparse : if statement is fixed<commit_after>package models

import (
	"errors"
	mongomodels "koding/db/models"
	"koding/db/mongodb/modelhelper"
	socialapimodels "socialapi/models"
	"strconv"
	"strings"
)

type Mail struct {
	FromName          string
	From              string
	OriginalRecipient string
	MailboxHash       string
	TextBody          string
	StrippedTextReply string
}

// errors
var (
	ErrNotValid          = errors.New("no valid content")
	ErrAccountIsNotFound = errors.New("Account is not found")
	ErrFromFieldIsNotSet = errors.New("From field is not set")
	ErrTextBodyIsNotSet  = errors.New("TextBody is not set")
	errInvalidMailPrefix = errors.New("invalid prefix")
)

// GetAccount gets the account which sent the message
func GetAccount(mailAddress string) (*mongomodels.Account, error) {
	user, err := modelhelper.FetchUserByEmail(mailAddress)
	if err != nil {
		return nil, err
	}

	account, err := modelhelper.GetAccount(user.Name)
	if err != nil {
		return nil, err
	}
	return account, nil
}

func (m *Mail) Validate() error {
	if m.From == "" {
		return ErrFromFieldIsNotSet
	}

	if m.TextBody == "" {
		return ErrTextBodyIsNotSet
	}

	return nil
}

// Examples of postmark inbound messages
// reply+messageid.1234@inbound.koding.com
// post+channelid.5678@inbound.koding.com
func (m *Mail) Persist() error {
	//acc := socialapimodels.NewAccount()
	acc, err := GetAccount(m.From)
	if err != nil {
		return errInvalidMailPrefix
	}

	accountId, err := acc.GetSocialApiId()
	if err != nil {
		return err
	}

	if strings.HasPrefix(m.OriginalRecipient, "post") {
		// Split method get the MailboxHash field
		// MailboxHash seems like "channelid.5678"
		s := strings.Split(m.MailboxHash, ".")
		// ParseInt get the 1. index (2.parameter) of "s" value
		// As explained above, we got 1. index that "5678" as string
		// and then, we convert string to int64
		cid, err := strconv.ParseInt(s[1], 10, 64)
		if err != nil {
			return err
		}

		channelId := cid
		c, err := socialapimodels.ChannelById(channelId)
		if err != nil {
			return err
		}

		cm := socialapimodels.NewChannelMessage()
		cm.Body = m.TextBody // set the body
		// todo set this type according to the the channel id
		cm.TypeConstant = socialapimodels.ChannelMessage_TYPE_POST
		cm.InitialChannelId = channelId
		cm.AccountId = accountId
		if err := cm.Create(); err != nil {
			return err
		}

		_, err = c.EnsureMessage(cm, true)
		if err != nil {
			return err
		}

		return nil
	}

	if strings.HasPrefix(m.OriginalRecipient, "reply") {
		s := strings.Split(m.MailboxHash, ".")
		mId, err := strconv.ParseInt(s[1], 10, 64)
		if err != nil {
			return err
		}
		messageId := mId
		cm, err := socialapimodels.ChannelMessageById(messageId)
		if err != nil {
			return err
		}

		// create reply
		reply := socialapimodels.NewChannelMessage()
		reply.Body = m.StrippedTextReply // set the body
		// todo set this type according to the the channel id
		reply.TypeConstant = socialapimodels.ChannelMessage_TYPE_REPLY
		reply.InitialChannelId = cm.InitialChannelId
		reply.AccountId = accountId
		if err := reply.Create(); err != nil {
			return err
		}

		if _, err = cm.AddReply(reply); err != nil {
			return err
		}

		return nil
	}

	return errInvalidMailPrefix

}
<|endoftext|>


<commit_before>// +build experimental

package source

import (
	"go/token"
	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/internal/span"
)

func getCodeActions(fset *token.FileSet, diag analysis.Diagnostic) ([]CodeAction, error) {
	var cas []CodeAction
	for _, fix := range diag.SuggestedFixes {
		var ca CodeAction
		ca.Title = fix.Message
		for _, te := range fix.TextEdits {
			span, err := span.NewRange(fset, te.Pos, te.End).Span()
			if err != nil {
				return nil, err
			}
			ca.Edits = append(ca.Edits, TextEdit{span, string(te.NewText)})
		}
		cas = append(cas, ca)
	}
	return cas, nil
}
<commit_msg>internal/lsp/source: fix renaming of SuggestedFixes in experimental file<commit_after>// +build experimental

package source

import (
	"go/token"
	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/internal/span"
)

func getCodeActions(fset *token.FileSet, diag analysis.Diagnostic) ([]SuggestedFixes, error) {
	var cas []SuggestedFixes
	for _, fix := range diag.SuggestedFixes {
		var ca SuggestedFixes
		ca.Title = fix.Message
		for _, te := range fix.TextEdits {
			span, err := span.NewRange(fset, te.Pos, te.End).Span()
			if err != nil {
				return nil, err
			}
			ca.Edits = append(ca.Edits, TextEdit{span, string(te.NewText)})
		}
		cas = append(cas, ca)
	}
	return cas, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package felixsyncer

import (
	"github.com/projectcalico/libcalico-go/lib/apiconfig"
	apiv3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
	"github.com/projectcalico/libcalico-go/lib/backend/api"
	"github.com/projectcalico/libcalico-go/lib/backend/model"
	"github.com/projectcalico/libcalico-go/lib/backend/syncersv1/updateprocessors"
	"github.com/projectcalico/libcalico-go/lib/backend/watchersyncer"
)

// New creates a new Felix v1 Syncer.
func New(client api.Client, cfg apiconfig.CalicoAPIConfigSpec, callbacks api.SyncerCallbacks, isLeader bool) api.Syncer {
	// Felix always needs ClusterInformation and FelixConfiguration resources.
	resourceTypes := []watchersyncer.ResourceType{
		{
			ListInterface:   model.ResourceListOptions{Kind: apiv3.KindClusterInformation},
			UpdateProcessor: updateprocessors.NewClusterInfoUpdateProcessor(),
		},
		{
			ListInterface:   model.ResourceListOptions{Kind: apiv3.KindFelixConfiguration},
			UpdateProcessor: updateprocessors.NewFelixConfigUpdateProcessor(),
		},
	}

	if isLeader {
		// These resources are only required if this is the active Felix instance on the node.
		additionalTypes := []watchersyncer.ResourceType{
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindGlobalNetworkPolicy},
				UpdateProcessor: updateprocessors.NewGlobalNetworkPolicyUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindGlobalNetworkSet},
				UpdateProcessor: updateprocessors.NewGlobalNetworkSetUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindIPPool},
				UpdateProcessor: updateprocessors.NewIPPoolUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNode},
				UpdateProcessor: updateprocessors.NewFelixNodeUpdateProcessor(cfg.K8sUsePodCIDR),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindProfile},
				UpdateProcessor: updateprocessors.NewProfileUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindWorkloadEndpoint},
				UpdateProcessor: updateprocessors.NewWorkloadEndpointUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNetworkPolicy},
				UpdateProcessor: updateprocessors.NewNetworkPolicyUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNetworkSet},
				UpdateProcessor: updateprocessors.NewNetworkSetUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindHostEndpoint},
				UpdateProcessor: updateprocessors.NewHostEndpointUpdateProcessor(),
			},
		}

		// If using Calico IPAM, include IPAM resources the felix cares about.
		if !cfg.K8sUsePodCIDR {
			additionalTypes = append(additionalTypes, watchersyncer.ResourceType{ListInterface: model.BlockListOptions{}})
		}

		resourceTypes = append(resourceTypes, additionalTypes...)
	}

	return watchersyncer.New(
		client,
		resourceTypes,
		callbacks,
	)
}
<commit_msg>Add BGPConfiguration to Felix syncer<commit_after>// Copyright (c) 2017-2020 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package felixsyncer

import (
	"github.com/projectcalico/libcalico-go/lib/apiconfig"
	apiv3 "github.com/projectcalico/libcalico-go/lib/apis/v3"
	"github.com/projectcalico/libcalico-go/lib/backend/api"
	"github.com/projectcalico/libcalico-go/lib/backend/model"
	"github.com/projectcalico/libcalico-go/lib/backend/syncersv1/updateprocessors"
	"github.com/projectcalico/libcalico-go/lib/backend/watchersyncer"
)

// New creates a new Felix v1 Syncer.
func New(client api.Client, cfg apiconfig.CalicoAPIConfigSpec, callbacks api.SyncerCallbacks, isLeader bool) api.Syncer {
	// Felix always needs ClusterInformation and FelixConfiguration resources.
	resourceTypes := []watchersyncer.ResourceType{
		{
			ListInterface:   model.ResourceListOptions{Kind: apiv3.KindClusterInformation},
			UpdateProcessor: updateprocessors.NewClusterInfoUpdateProcessor(),
		},
		{
			ListInterface:   model.ResourceListOptions{Kind: apiv3.KindFelixConfiguration},
			UpdateProcessor: updateprocessors.NewFelixConfigUpdateProcessor(),
		},
	}

	if isLeader {
		// These resources are only required if this is the active Felix instance on the node.
		additionalTypes := []watchersyncer.ResourceType{
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindGlobalNetworkPolicy},
				UpdateProcessor: updateprocessors.NewGlobalNetworkPolicyUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindGlobalNetworkSet},
				UpdateProcessor: updateprocessors.NewGlobalNetworkSetUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindIPPool},
				UpdateProcessor: updateprocessors.NewIPPoolUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNode},
				UpdateProcessor: updateprocessors.NewFelixNodeUpdateProcessor(cfg.K8sUsePodCIDR),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindProfile},
				UpdateProcessor: updateprocessors.NewProfileUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindWorkloadEndpoint},
				UpdateProcessor: updateprocessors.NewWorkloadEndpointUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNetworkPolicy},
				UpdateProcessor: updateprocessors.NewNetworkPolicyUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindNetworkSet},
				UpdateProcessor: updateprocessors.NewNetworkSetUpdateProcessor(),
			},
			{
				ListInterface:   model.ResourceListOptions{Kind: apiv3.KindHostEndpoint},
				UpdateProcessor: updateprocessors.NewHostEndpointUpdateProcessor(),
			},
			{
				ListInterface: model.ResourceListOptions{Kind: apiv3.KindBGPConfiguration},
			},
		}

		// If using Calico IPAM, include IPAM resources the felix cares about.
		if !cfg.K8sUsePodCIDR {
			additionalTypes = append(additionalTypes, watchersyncer.ResourceType{ListInterface: model.BlockListOptions{}})
		}

		resourceTypes = append(resourceTypes, additionalTypes...)
	}

	return watchersyncer.New(
		client,
		resourceTypes,
		callbacks,
	)
}
<|endoftext|>


<commit_before>package cs

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/denverdino/aliyungo/common"
)

type TaskState string

const (
	// task status
	Task_Status_Running = "running"
	Task_Status_Success = "Success"
	Task_Status_Failed  = "Failed"

	// upgrade state
	UpgradeStep_NotStart    = "not_start"
	UpgradeStep_Prechecking = "prechecking"
	UpgradeStep_Upgrading   = "upgrading"
	UpgradeStep_Pause       = "pause"
	UpgradeStep_Success     = "success"
)

//modify cluster,include DeletionProtection and so on
type ModifyClusterArgs struct {
	DeletionProtection bool `json:"deletion_protection"`
}

type UpgradeClusterArgs struct {
	Version string `json:"version"`
}

type UpgradeClusterResult struct {
	Status           TaskState `json:"status"`
	PrecheckReportId string    `json:"precheck_report_id"`
	UpgradeStep      string    `json:"upgrade_step"`
	ErrorMessage     string    `json:"error_message"`
	*UpgradeTask     `json:"upgrade_task,omitempty"`
}

type UpgradeTask struct {
	FieldRetries    int           `json:"retries,omitempty"`
	FieldCreatedAt  time.Time     `json:"created_at"`
	FieldMessage    string        `json:"message,omitempty"`
	FieldStatus     string        `json:"status"` // empty|running|success|failed
	FieldFinishedAt time.Time     `json:"finished_at,omitempty"`
	UpgradeStatus   UpgradeStatus `json:"upgrade_status"`
}

type UpgradeStatus struct {
	State      string  `json:"state"`
	Phase      string  `json:"phase"` // {Master1, Master2, Master3, Nodes}
	Total      int     `json:"total"`
	Succeeded  int     `json:"succeeded"`
	Failed     string  `json:"failed"`
	Events     []Event `json:"events"`
	IsCanceled bool    `json:"is_canceled"`
}

type Event struct {
	Timestamp time.Time
	Type      string
	Reason    string
	Message   string
	Source    string
}

//modify cluster
func (client *Client) ModifyCluster(clusterId string, args *ModifyClusterArgs) error {
	return client.Invoke("", http.MethodPut, "/api/v2/clusters/"+clusterId, nil, args, nil)
}

//upgrade cluster
func (client *Client) UpgradeCluster(clusterId string, args *UpgradeClusterArgs) error {
	return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade", clusterId), nil, args, nil)
}

//cancel upgrade cluster
func (client *Client) CancelUpgradeCluster(clusterId string) error {
	return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade/cancel", clusterId), nil, nil, nil)
}

func (client *Client) QueryUpgradeClusterResult(clusterId string) (*UpgradeClusterResult, error) {
	cluster := &UpgradeClusterResult{}
	err := client.Invoke("", http.MethodGet, fmt.Sprintf("/api/v2/clusters/%s/upgrade/status", clusterId), nil, nil, cluster)
	if err != nil {
		return nil, err
	}
	return cluster, nil
}

//Cluster Info
type KubernetesClusterType string

var (
	DelicatedKubernetes  = KubernetesClusterType("Kubernetes")
	ManagedKubernetes    = KubernetesClusterType("ManagedKubernetes")
	ServerlessKubernetes = KubernetesClusterType("Ask")
)

type ProxyMode string

var (
	IPTables = "iptables"
	IPVS     = "ipvs"
)

type Effect string

var (
	TaintNoExecute        = "NoExecute"
	TaintNoSchedule       = "NoSchedule"
	TaintPreferNoSchedule = "PreferNoSchedule"
)

type ClusterArgs struct {
	DisableRollback bool `json:"disable_rollback"`
	TimeoutMins     int  `json:"timeout_mins"`

	Name               string                `json:"name"`
	ClusterType        KubernetesClusterType `json:"cluster_type"`
	Profile            string                `json:"profile"`
	KubernetesVersion  string                `json:"kubernetes_version"`
	DeletionProtection bool                  `json:"deletion_protection"`

	NodeCidrMask string `json:"node_cidr_mask"`
	UserCa       string `json:"user_ca"`

	OsType   string `json:"os_type"`
	Platform string `json:"platform"`

	UserData string `json:"user_data"`

	NodePortRange string `json:"node_port_range"`

	//ImageId
	ImageId string `json:"image_id"`

	PodVswitchIds []string `json:"pod_vswitch_ids"` // eni多网卡模式下，需要传额外的vswitchid给addon

	LoginPassword string `json:"login_password"` //和KeyPair 二选一
	KeyPair       string `json:"key_pair"`       ////LoginPassword 二选一

	RegionId      common.Region `json:"region_id"`
	VpcId         string        `json:"vpcid"`
	ContainerCidr string        `json:"container_cidr"`
	ServiceCidr   string        `json:"service_cidr"`

	CloudMonitorFlags bool `json:"cloud_monitor_flags"`

	SecurityGroupId      string    `json:"security_group_id"`
	EndpointPublicAccess bool      `json:"endpoint_public_access"`
	ProxyMode            ProxyMode `json:"proxy_mode"`
	SnatEntry            bool      `json:"snat_entry"`

	Addons []Addon `json:"addons"`
	Tags   []Tag   `json:"tags"`

	Taints []Taint `json:"taints"`
}

//addon
type Addon struct {
	Name    string `json:"name"`
	Version string `json:"version"`
	Config  string `json:"config"`
}

//taint
type Taint struct {
	Key    string `json:"key"`
	Value  string `json:"value"`
	Effect Effect `json:"effect"`
}

type MasterArgs struct {
	MasterCount         int      `json:"master_count"`
	MasterVSwitchIds    []string `json:"master_vswitch_ids"`
	MasterInstanceTypes []string `json:"master_instance_types"`

	MasterInstanceChargeType string `json:"master_instance_charge_type"`
	MasterPeriod             int    `json:"master_period"`
	MasterPeriodUnit         string `json:"master_period_unit"`

	MasterAutoRenew       bool `json:"master_auto_renew"`
	MasterAutoRenewPeriod int  `json:"master_auto_renew_period"`

	MasterSystemDiskCategory string `json:"master_system_disk_category"`
	MasterSystemDiskSize     int64  `json:"master_system_disk_size"`

	MasterDataDisks []DataDisk `json:"master_data_disks"` //支持多个数据盘

	//support hpc/scc
	MasterHpcClusterId    string `json:"master_hpc_cluster_id"`
	MasterDeploymentSetId string `json:"master_deploymentset_id"`

	//master node deletion protection
	MasterDeletionProtection *bool `json:"master_deletion_protection"`

	// disk snapshot policy
	MasterSnapshotPolicyId string `json:"master_system_disk_snapshot_policy_id"`
}

type WorkerArgs struct {
	WorkerVSwitchIds    []string `json:"worker_vswitch_ids"`
	WorkerInstanceTypes []string `json:"worker_instance_types"`

	NumOfNodes int64 `json:"num_of_nodes"`

	WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
	WorkerPeriod             int    `json:"worker_period"`
	WorkerPeriodUnit         string `json:"worker_period_unit"`

	WorkerAutoRenew       bool `json:"worker_auto_renew"`
	WorkerAutoRenewPeriod int  `json:"worker_auto_renew_period"`

	WorkerSystemDiskCategory string `json:"worker_system_disk_category"`
	WorkerSystemDiskSize     int64  `json:"worker_system_disk_size"`

	WorkerDataDisk  bool       `json:"worker_data_disk"`
	WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘

	WorkerHpcClusterId    string `json:"worker_hpc_cluster_id"`
	WorkerDeploymentSetId string `json:"worker_deploymentset_id"`

	//worker node deletion protection
	WorkerDeletionProtection *bool `json:"worker_deletion_protection"`

	//Runtime only for worker nodes
	Runtime Runtime `json:"runtime"`

	// disk snapshot policy
	WorkerSnapshotPolicyId string `json:"worker_system_disk_snapshot_policy_id"`
}

type ScaleOutKubernetesClusterRequest struct {
	LoginPassword string `json:"login_password"` //和KeyPair 二选一
	KeyPair       string `json:"key_pair"`       ////LoginPassword 二选一

	WorkerVSwitchIds    []string `json:"worker_vswitch_ids"`
	WorkerInstanceTypes []string `json:"worker_instance_types"`

	WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
	WorkerPeriod             int    `json:"worker_period"`
	WorkerPeriodUnit         string `json:"worker_period_unit"`

	WorkerAutoRenew       bool `json:"worker_auto_renew"`
	WorkerAutoRenewPeriod int  `json:"worker_auto_renew_period"`

	WorkerDataDisk  bool       `json:"worker_data_disk"`
	WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘

	Tags    []Tag   `json:"tags"`
	Taints  []Taint `json:"taints"`
	ImageId string  `json:"image_id"`

	UserData string `json:"user_data"`

	Count int64 `json:"count"`
}

//datadiks
type DataDisk struct {
	Category             string `json:"category"`
	KMSKeyId             string `json:"kms_key_id"`
	Encrypted            string `json:"encrypted"` // true|false
	Device               string `json:"device"`    //  could be /dev/xvd[a-z]. If not specification, will use default value.
	Size                 string `json:"size"`
	DiskName             string `json:"name"`
	AutoSnapshotPolicyId string `json:"auto_snapshot_policy_id"`
}

//runtime
type Runtime struct {
	Name                       string   `json:"name"`
	Version                    string   `json:"version"`
	RuntimeClass               []string `json:"runtimeClass,omitempty"`
	Exist                      bool     `json:"exist"`
	AvailableNetworkComponents []string `json:"availableNetworkComponents,omitempty"`
}

//DelicatedKubernetes
type DelicatedKubernetesClusterCreationRequest struct {
	ClusterArgs
	MasterArgs
	WorkerArgs
}

//ManagedKubernetes
type ManagedKubernetesClusterCreationRequest struct {
	ClusterArgs
	WorkerArgs
}

//Validate

//Create DelicatedKubernetes Cluster
func (client *Client) CreateDelicatedKubernetesCluster(request *DelicatedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke(request.RegionId, http.MethodPost, "/clusters", nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//Create ManagedKubernetes Cluster
func (client *Client) CreateManagedKubernetesCluster(request *ManagedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke(request.RegionId, http.MethodPost, "/clusters", nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//ScaleKubernetesCluster
func (client *Client) ScaleOutKubernetesCluster(clusterId string, request *ScaleOutKubernetesClusterRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s", clusterId), nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//DeleteClusterNodes
type DeleteKubernetesClusterNodesRequest struct {
	ReleaseNode bool     `json:"release_node"` //if set to true, the ecs instance will be released
	Nodes       []string `json:"nodes"`        //the format is regionId.instanceId|Ip ,for example  cn-hangzhou.192.168.1.2 or cn-hangzhou.i-abc
	DrainNode   bool     `json:"drain_node"`   //same as Nodes
}

//DeleteClusterNodes
func (client *Client) DeleteKubernetesClusterNodes(clusterId string, request *DeleteKubernetesClusterNodesRequest) (*common.Response, error) {
	response := &common.Response{}
	err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/nodes/remove", clusterId), nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//Cluster definition
type KubernetesClusterDetail struct {
	RegionId common.Region `json:"region_id"`

	Name        string                `json:"name"`
	ClusterId   string                `json:"cluster_id"`
	Size        int64                 `json:"size"`
	ClusterType KubernetesClusterType `json:"cluster_type"`
	Profile     string                `json:"profile"`

	VpcId                 string `json:"vpc_id"`
	VSwitchIds            string `json:"vswitch_id"`
	SecurityGroupId       string `json:"security_group_id"`
	IngressLoadbalancerId string `json:"external_loadbalancer_id"`
	ResourceGroupId       string `json:"resource_group_id"`
	NetworkMode           string `json:"network_mode"`
	ContainerCIDR         string `json:"subnet_cidr"`

	Tags  []Tag  `json:"tags"`
	State string `json:"state"`

	InitVersion        string `json:"init_version"`
	CurrentVersion     string `json:"current_version"`
	PrivateZone        bool   `json:"private_zone"`
	DeletionProtection bool   `json:"deletion_protection"`
	MetaData           string `json:"meta_data"`

	Created time.Time `json:"created"`
	Updated time.Time `json:"updated"`
}

//GetMetaData
func (c *KubernetesClusterDetail) GetMetaData() map[string]interface{} {
	m := make(map[string]interface{})
	_ = json.Unmarshal([]byte(c.MetaData), &m)
	return m
}

//查询集群详情
func (client *Client) DescribeKubernetesClusterDetail(clusterId string) (*KubernetesClusterDetail, error) {
	cluster := &KubernetesClusterDetail{}
	err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId, nil, nil, cluster)
	if err != nil {
		return nil, err
	}
	return cluster, nil
}

//DeleteKubernetesCluster
func (client *Client) DeleteKubernetesCluster(clusterId string) error {
	return client.Invoke("", http.MethodDelete, "/clusters/"+clusterId, nil, nil, nil)
}
<commit_msg>support more ack props<commit_after>package cs

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/denverdino/aliyungo/common"
)

type TaskState string

const (
	// task status
	Task_Status_Running = "running"
	Task_Status_Success = "Success"
	Task_Status_Failed  = "Failed"

	// upgrade state
	UpgradeStep_NotStart    = "not_start"
	UpgradeStep_Prechecking = "prechecking"
	UpgradeStep_Upgrading   = "upgrading"
	UpgradeStep_Pause       = "pause"
	UpgradeStep_Success     = "success"
)

//modify cluster,include DeletionProtection and so on
type ModifyClusterArgs struct {
	DeletionProtection bool `json:"deletion_protection"`
}

type UpgradeClusterArgs struct {
	Version string `json:"version"`
}

type UpgradeClusterResult struct {
	Status           TaskState `json:"status"`
	PrecheckReportId string    `json:"precheck_report_id"`
	UpgradeStep      string    `json:"upgrade_step"`
	ErrorMessage     string    `json:"error_message"`
	*UpgradeTask     `json:"upgrade_task,omitempty"`
}

type UpgradeTask struct {
	FieldRetries    int           `json:"retries,omitempty"`
	FieldCreatedAt  time.Time     `json:"created_at"`
	FieldMessage    string        `json:"message,omitempty"`
	FieldStatus     string        `json:"status"` // empty|running|success|failed
	FieldFinishedAt time.Time     `json:"finished_at,omitempty"`
	UpgradeStatus   UpgradeStatus `json:"upgrade_status"`
}

type UpgradeStatus struct {
	State      string  `json:"state"`
	Phase      string  `json:"phase"` // {Master1, Master2, Master3, Nodes}
	Total      int     `json:"total"`
	Succeeded  int     `json:"succeeded"`
	Failed     string  `json:"failed"`
	Events     []Event `json:"events"`
	IsCanceled bool    `json:"is_canceled"`
}

type Event struct {
	Timestamp time.Time
	Type      string
	Reason    string
	Message   string
	Source    string
}

//modify cluster
func (client *Client) ModifyCluster(clusterId string, args *ModifyClusterArgs) error {
	return client.Invoke("", http.MethodPut, "/api/v2/clusters/"+clusterId, nil, args, nil)
}

//upgrade cluster
func (client *Client) UpgradeCluster(clusterId string, args *UpgradeClusterArgs) error {
	return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade", clusterId), nil, args, nil)
}

//cancel upgrade cluster
func (client *Client) CancelUpgradeCluster(clusterId string) error {
	return client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/upgrade/cancel", clusterId), nil, nil, nil)
}

func (client *Client) QueryUpgradeClusterResult(clusterId string) (*UpgradeClusterResult, error) {
	cluster := &UpgradeClusterResult{}
	err := client.Invoke("", http.MethodGet, fmt.Sprintf("/api/v2/clusters/%s/upgrade/status", clusterId), nil, nil, cluster)
	if err != nil {
		return nil, err
	}
	return cluster, nil
}

//Cluster Info
type KubernetesClusterType string

var (
	DelicatedKubernetes  = KubernetesClusterType("Kubernetes")
	ManagedKubernetes    = KubernetesClusterType("ManagedKubernetes")
	ServerlessKubernetes = KubernetesClusterType("Ask")
)

type ProxyMode string

var (
	IPTables = "iptables"
	IPVS     = "ipvs"
)

type Effect string

var (
	TaintNoExecute        = "NoExecute"
	TaintNoSchedule       = "NoSchedule"
	TaintPreferNoSchedule = "PreferNoSchedule"
)

type ClusterArgs struct {
	DisableRollback bool `json:"disable_rollback"`
	TimeoutMins     int  `json:"timeout_mins"`

	Name               string                `json:"name"`
	ClusterType        KubernetesClusterType `json:"cluster_type"`
	Profile            string                `json:"profile"`
	KubernetesVersion  string                `json:"kubernetes_version"`
	DeletionProtection bool                  `json:"deletion_protection"`

	NodeCidrMask string `json:"node_cidr_mask"`
	UserCa       string `json:"user_ca"`

	OsType   string `json:"os_type"`
	Platform string `json:"platform"`

	UserData string `json:"user_data"`

	NodePortRange string `json:"node_port_range"`
	NodeNameMode string  `json:"node_name_mode"`

	//ImageId
	ImageId string `json:"image_id"`

	PodVswitchIds []string `json:"pod_vswitch_ids"` // eni多网卡模式下，需要传额外的vswitchid给addon

	LoginPassword string `json:"login_password"` //和KeyPair 二选一
	KeyPair       string `json:"key_pair"`       ////LoginPassword 二选一

	RegionId      common.Region `json:"region_id"`
	VpcId         string        `json:"vpcid"`
	ContainerCidr string        `json:"container_cidr"`
	ServiceCidr   string        `json:"service_cidr"`

	CloudMonitorFlags bool `json:"cloud_monitor_flags"`

	SecurityGroupId      string    `json:"security_group_id"`
	EndpointPublicAccess bool      `json:"endpoint_public_access"`
	ProxyMode            ProxyMode `json:"proxy_mode"`
	SnatEntry            bool      `json:"snat_entry"`

	Addons []Addon `json:"addons"`
	Tags   []Tag   `json:"tags"`

	Taints       []Taint `json:"taints"`
}

//addon
type Addon struct {
	Name     string `json:"name"`
	Version  string `json:"version"`
	Config   string `json:"config"`
	Disabled bool   `json:"disabled"` // 是否禁止默认安装
}

//taint
type Taint struct {
	Key    string `json:"key"`
	Value  string `json:"value"`
	Effect Effect `json:"effect"`
}

type MasterArgs struct {
	MasterCount         int      `json:"master_count"`
	MasterVSwitchIds    []string `json:"master_vswitch_ids"`
	MasterInstanceTypes []string `json:"master_instance_types"`

	MasterInstanceChargeType string `json:"master_instance_charge_type"`
	MasterPeriod             int    `json:"master_period"`
	MasterPeriodUnit         string `json:"master_period_unit"`

	MasterAutoRenew       bool `json:"master_auto_renew"`
	MasterAutoRenewPeriod int  `json:"master_auto_renew_period"`

	MasterSystemDiskCategory string `json:"master_system_disk_category"`
	MasterSystemDiskSize     int64  `json:"master_system_disk_size"`

	MasterDataDisks []DataDisk `json:"master_data_disks"` //支持多个数据盘

	//support hpc/scc
	MasterHpcClusterId    string `json:"master_hpc_cluster_id"`
	MasterDeploymentSetId string `json:"master_deploymentset_id"`

	//master node deletion protection
	MasterDeletionProtection *bool `json:"master_deletion_protection"`

	// disk snapshot policy
	MasterSnapshotPolicyId string `json:"master_system_disk_snapshot_policy_id"`
}

type WorkerArgs struct {
	WorkerVSwitchIds    []string `json:"worker_vswitch_ids"`
	WorkerInstanceTypes []string `json:"worker_instance_types"`

	NumOfNodes int64 `json:"num_of_nodes"`

	WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
	WorkerPeriod             int    `json:"worker_period"`
	WorkerPeriodUnit         string `json:"worker_period_unit"`

	WorkerAutoRenew       bool `json:"worker_auto_renew"`
	WorkerAutoRenewPeriod int  `json:"worker_auto_renew_period"`

	WorkerSystemDiskCategory string `json:"worker_system_disk_category"`
	WorkerSystemDiskSize     int64  `json:"worker_system_disk_size"`

	WorkerDataDisk  bool       `json:"worker_data_disk"`
	WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘

	WorkerHpcClusterId    string `json:"worker_hpc_cluster_id"`
	WorkerDeploymentSetId string `json:"worker_deploymentset_id"`

	//worker node deletion protection
	WorkerDeletionProtection *bool `json:"worker_deletion_protection"`

	//Runtime only for worker nodes
	Runtime Runtime `json:"runtime"`

	// disk snapshot policy
	WorkerSnapshotPolicyId string `json:"worker_system_disk_snapshot_policy_id"`
}

type ScaleOutKubernetesClusterRequest struct {
	LoginPassword string `json:"login_password"` //和KeyPair 二选一
	KeyPair       string `json:"key_pair"`       ////LoginPassword 二选一

	WorkerVSwitchIds    []string `json:"worker_vswitch_ids"`
	WorkerInstanceTypes []string `json:"worker_instance_types"`

	WorkerInstanceChargeType string `json:"worker_instance_charge_type"`
	WorkerPeriod             int    `json:"worker_period"`
	WorkerPeriodUnit         string `json:"worker_period_unit"`

	WorkerAutoRenew       bool `json:"worker_auto_renew"`
	WorkerAutoRenewPeriod int  `json:"worker_auto_renew_period"`

	WorkerDataDisk  bool       `json:"worker_data_disk"`
	WorkerDataDisks []DataDisk `json:"worker_data_disks"` //支持多个数据盘

	Tags    []Tag   `json:"tags"`
	Taints  []Taint `json:"taints"`
	ImageId string  `json:"image_id"`

	UserData string `json:"user_data"`

	Count int64 `json:"count"`
}

//datadiks
type DataDisk struct {
	Category             string `json:"category"`
	KMSKeyId             string `json:"kms_key_id"`
	Encrypted            string `json:"encrypted"` // true|false
	Device               string `json:"device"`    //  could be /dev/xvd[a-z]. If not specification, will use default value.
	Size                 string `json:"size"`
	DiskName             string `json:"name"`
	AutoSnapshotPolicyId string `json:"auto_snapshot_policy_id"`
}

//runtime
type Runtime struct {
	Name                       string   `json:"name"`
	Version                    string   `json:"version"`
	RuntimeClass               []string `json:"runtimeClass,omitempty"`
	Exist                      bool     `json:"exist"`
	AvailableNetworkComponents []string `json:"availableNetworkComponents,omitempty"`
}

//DelicatedKubernetes
type DelicatedKubernetesClusterCreationRequest struct {
	ClusterArgs
	MasterArgs
	WorkerArgs
}

//ManagedKubernetes
type ManagedKubernetesClusterCreationRequest struct {
	ClusterArgs
	WorkerArgs
}

//Validate

//Create DelicatedKubernetes Cluster
func (client *Client) CreateDelicatedKubernetesCluster(request *DelicatedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke(request.RegionId, http.MethodPost, "/clusters", nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//Create ManagedKubernetes Cluster
func (client *Client) CreateManagedKubernetesCluster(request *ManagedKubernetesClusterCreationRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke(request.RegionId, http.MethodPost, "/clusters", nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//ScaleKubernetesCluster
func (client *Client) ScaleOutKubernetesCluster(clusterId string, request *ScaleOutKubernetesClusterRequest) (*ClusterCommonResponse, error) {
	response := &ClusterCommonResponse{}
	err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s", clusterId), nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//DeleteClusterNodes
type DeleteKubernetesClusterNodesRequest struct {
	ReleaseNode bool     `json:"release_node"` //if set to true, the ecs instance will be released
	Nodes       []string `json:"nodes"`        //the format is regionId.instanceId|Ip ,for example  cn-hangzhou.192.168.1.2 or cn-hangzhou.i-abc
	DrainNode   bool     `json:"drain_node"`   //same as Nodes
}

//DeleteClusterNodes
func (client *Client) DeleteKubernetesClusterNodes(clusterId string, request *DeleteKubernetesClusterNodesRequest) (*common.Response, error) {
	response := &common.Response{}
	err := client.Invoke("", http.MethodPost, fmt.Sprintf("/api/v2/clusters/%s/nodes/remove", clusterId), nil, request, response)
	if err != nil {
		return nil, err
	}

	return response, nil
}

//Cluster definition
type KubernetesClusterDetail struct {
	RegionId common.Region `json:"region_id"`

	Name        string                `json:"name"`
	ClusterId   string                `json:"cluster_id"`
	Size        int64                 `json:"size"`
	ClusterType KubernetesClusterType `json:"cluster_type"`
	Profile     string                `json:"profile"`

	VpcId                 string `json:"vpc_id"`
	VSwitchIds            string `json:"vswitch_id"`
	SecurityGroupId       string `json:"security_group_id"`
	IngressLoadbalancerId string `json:"external_loadbalancer_id"`
	ResourceGroupId       string `json:"resource_group_id"`
	NetworkMode           string `json:"network_mode"`
	ContainerCIDR         string `json:"subnet_cidr"`

	Tags  []Tag  `json:"tags"`
	State string `json:"state"`

	InitVersion        string `json:"init_version"`
	CurrentVersion     string `json:"current_version"`
	PrivateZone        bool   `json:"private_zone"`
	DeletionProtection bool   `json:"deletion_protection"`
	MetaData           string `json:"meta_data"`

	Created time.Time `json:"created"`
	Updated time.Time `json:"updated"`

	WorkerRamRoleName string `json:"worker_ram_role_name"`
}

//GetMetaData
func (c *KubernetesClusterDetail) GetMetaData() map[string]interface{} {
	m := make(map[string]interface{})
	_ = json.Unmarshal([]byte(c.MetaData), &m)
	return m
}

//查询集群详情
func (client *Client) DescribeKubernetesClusterDetail(clusterId string) (*KubernetesClusterDetail, error) {
	cluster := &KubernetesClusterDetail{}
	err := client.Invoke("", http.MethodGet, "/clusters/"+clusterId, nil, nil, cluster)
	if err != nil {
		return nil, err
	}
	return cluster, nil
}

//DeleteKubernetesCluster
func (client *Client) DeleteKubernetesCluster(clusterId string) error {
	return client.Invoke("", http.MethodDelete, "/clusters/"+clusterId, nil, nil, nil)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"runtime/pprof"
	"strings"
	"sync"
)

var post = flag.String("post", "", "HTTP address to make a POST request to.  data will be in the body.")
var get = flag.String("get", "", "HTTP address to make a GET request to. '%s' will be printf replaced with data.")
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
var numPublishers = flag.Int("n", 5, "Number of concurrent publishers")
var showVersion = flag.Bool("version", false, "print version string")

const VERSION = "0.2"

type Publisher interface {
	Publish(string) error
}

type PublisherInfo struct {
	addr string
}

type PostPublisher struct {
	PublisherInfo
}

func (p *PostPublisher) Publish(msg string) error {
	reader := bytes.NewReader([]byte(msg))
	resp, err := http.Post(p.addr, "application/octet-stream", reader)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

type GetPublisher struct {
	PublisherInfo
}

func (p *GetPublisher) Publish(msg string) error {
	endpoint := fmt.Sprintf(p.addr, url.QueryEscape(msg))
	resp, err := http.Get(endpoint)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

func PublishLoop(waitGroup *sync.WaitGroup, pub Publisher, publishMsgs chan string) {
	for msg := range publishMsgs {
		err := pub.Publish(msg)
		if err != nil {
			log.Printf("ERROR: publishing '%s' - %s", msg, err.Error())
		}
	}
	waitGroup.Done()
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Printf("file2http v%s\n", VERSION)
		return
	}

	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	var publisher Publisher
	if len(*post) > 0 {
		publisher = &PostPublisher{PublisherInfo{*post}}
	} else if len(*get) > 0 {
		if strings.Count(*get, "%s") != 1 {
			log.Fatal("Invalid get address - must be a format string")
		}
		publisher = &GetPublisher{PublisherInfo{*get}}
	} else {
		log.Fatal("Need get or post address!")
	}

	msgsChan := make(chan string)
	waitGroup := &sync.WaitGroup{}
	waitGroup.Add(*numPublishers)
	for i := 0; i < *numPublishers; i++ {
		go PublishLoop(waitGroup, publisher, msgsChan)
	}
	reader := bufio.NewReader(os.Stdin)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Println(fmt.Sprintf("ERROR: %s", err))
			}
			break
		}
		line = strings.TrimSpace(line)
		msgsChan <- line
	}
	close(msgsChan)
	waitGroup.Wait()
}
<commit_msg>minor tweaks and cleanup (particularly make sure post sends content-size)<commit_after>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
	"sync"
)

var post = flag.String("post", "", "HTTP address to make a POST request to.  data will be in the body.")
var get = flag.String("get", "", "HTTP address to make a GET request to. '%s' will be printf replaced with data.")
var numPublishers = flag.Int("n", 5, "Number of concurrent publishers")
var showVersion = flag.Bool("version", false, "print version string")

const VERSION = "0.3"

type Publisher interface {
	Publish(string) error
}

type PublisherInfo struct {
	addr string
}

type PostPublisher struct {
	PublisherInfo
}

func (p *PostPublisher) Publish(msg string) error {
	buf := bytes.NewBuffer([]byte(msg))
	resp, err := http.Post(p.addr, "application/octet-stream", buf)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

type GetPublisher struct {
	PublisherInfo
}

func (p *GetPublisher) Publish(msg string) error {
	endpoint := fmt.Sprintf(p.addr, url.QueryEscape(msg))
	resp, err := http.Get(endpoint)
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}

func PublishLoop(waitGroup *sync.WaitGroup, pub Publisher, publishMsgs chan string) {
	for msg := range publishMsgs {
		err := pub.Publish(msg)
		if err != nil {
			log.Printf("ERROR: publishing '%s' - %s", msg, err.Error())
		}
	}
	waitGroup.Done()
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Printf("file2http v%s\n", VERSION)
		return
	}

	var publisher Publisher
	if len(*post) > 0 {
		publisher = &PostPublisher{PublisherInfo{*post}}
	} else if len(*get) > 0 {
		if strings.Count(*get, "%s") != 1 {
			log.Fatal("Invalid get address - must be a format string")
		}
		publisher = &GetPublisher{PublisherInfo{*get}}
	} else {
		log.Fatal("Need get or post address!")
	}

	msgsChan := make(chan string)
	waitGroup := &sync.WaitGroup{}
	waitGroup.Add(*numPublishers)
	for i := 0; i < *numPublishers; i++ {
		go PublishLoop(waitGroup, publisher, msgsChan)
	}

	reader := bufio.NewReader(os.Stdin)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				log.Println(fmt.Sprintf("ERROR: %s", err))
			}
			break
		}
		line = strings.TrimSpace(line)
		msgsChan <- line
	}

	close(msgsChan)
	waitGroup.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"mime"
	"net/http"
	"os"
	"path/filepath"
        "strings"
)

func serveFile(w http.ResponseWriter, r *http.Request) {

	path := ""
        file := strings.Trim(r.FormValue("file"),  `./\`)
        size := r.FormValue("size")
	if size == "" {
		//original
		path = filepath.Join(filepath.Dir(os.Args[0]), galleryPath, r.FormValue("gallery"), file)
	} else {
		//thumbnail
		path = filepath.Join(filepath.Dir(os.Args[0]), galleryPath, r.FormValue("gallery"), fmt.Sprintf("thumbs%s", size), file)
	}

        ext := filepath.Ext(path)
        if !isPictureExt(ext) {
           fmt.Fprintln(w, "Not an image file")
           return
        }

	//Or ioutil.ReadFile...
	file, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		fmt.Fprintf(w, "Cannot open file %s", r.FormValue("file"))
		return
	}
	defer file.Close()
	//set content type
	mimeType := mime.TypeByExtension(ext)
	if mimeType != "" {
		w.Header().Set("Content-Type", mimeType)
	}
	//output data
	io.Copy(w, file)

	return
}
<commit_msg>fix var<commit_after>package main

import (
	"fmt"
	"io"
	"mime"
	"net/http"
	"os"
	"path/filepath"
        "strings"
)

func serveFile(w http.ResponseWriter, r *http.Request) {

	path := ""
        file := strings.Trim(r.FormValue("file"),  `./\`)
        size := r.FormValue("size")
	if size == "" {
		//original
		path = filepath.Join(filepath.Dir(os.Args[0]), galleryPath, r.FormValue("gallery"), file)
	} else {
		//thumbnail
		path = filepath.Join(filepath.Dir(os.Args[0]), galleryPath, r.FormValue("gallery"), fmt.Sprintf("thumbs%s", size), file)
	}

        ext := filepath.Ext(path)
        if !isPictureExt(ext) {
           fmt.Fprintln(w, "Not an image file")
           return
        }

	//Or ioutil.ReadFile...
	fh, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		fmt.Fprintf(w, "Cannot open file %s", r.FormValue("file"))
		return
	}
	defer fh.Close()
	//set content type
	mimeType := mime.TypeByExtension(ext)
	if mimeType != "" {
		w.Header().Set("Content-Type", mimeType)
	}
	//output data
	io.Copy(w, fh)

	return
}
<|endoftext|>


<commit_before>package action_test

import (
	. "bosh/agent/action"
	fakeplatform "bosh/platform/fakes"
	boshsys "bosh/system"
	. "github.com/onsi/ginkgo"
	"github.com/stretchr/testify/assert"
)

func buildPrepareAction() (action PrepareNetworkChangeAction, fs boshsys.FileSystem) {
	platform := fakeplatform.NewFakePlatform()
	fs = platform.GetFs()
	action = NewPrepareNetworkChange(platform)

	return
}
func init() {
	Describe("Testing with Ginkgo", func() {
		It("prepare network change should be synchronous", func() {
			action, _ := buildPrepareAction()
			assert.False(GinkgoT(), action.IsAsynchronous())
		})
		It("prepare network change", func() {

			action, fs := buildPrepareAction()
			fs.WriteFile("/etc/udev/rules.d/70-persistent-net.rules", []byte{})

			resp, err := action.Run()

			assert.NoError(GinkgoT(), err)
			assert.Equal(GinkgoT(), "ok", resp)
			assert.False(GinkgoT(), fs.FileExists("/etc/udev/rules.d/70-persistent-net.rules"))
		})
	})
}
<commit_msg>formatting prepare_network_change_test.go<commit_after>package action_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "bosh/agent/action"
	fakeplatform "bosh/platform/fakes"
	boshsys "bosh/system"
)

func buildPrepareNetworkChangeAction() (PrepareNetworkChangeAction, boshsys.FileSystem) {
	platform := fakeplatform.NewFakePlatform()
	return NewPrepareNetworkChange(platform), platform.GetFs()
}

func init() {
	Describe("prepareNetworkChange", func() {
		It("is synchronous", func() {
			action, _ := buildPrepareNetworkChangeAction()
			Expect(action.IsAsynchronous()).To(BeFalse())
		})

		It("removes the network rules file", func() {
			action, fs := buildPrepareNetworkChangeAction()
			fs.WriteFile("/etc/udev/rules.d/70-persistent-net.rules", []byte{})

			resp, err := action.Run()
			Expect(err).NotTo(HaveOccurred())
			Expect(resp).To(Equal("ok"))
			Expect(fs.FileExists("/etc/udev/rules.d/70-persistent-net.rules")).To(BeFalse())
		})
	})
}
<|endoftext|>


<commit_before>package acceptance_tests

import (
	"crypto/tls"
	"fmt"
	"net/http"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
)

var _ = Describe("HTTPS Frontend", func() {
	var haproxyInfo haproxyInfo
	var closeTunnel func()
	var closeLocalServer func()
	enableHTTP2 := false
	var http1Client *http.Client

	haproxyBackendPort := 12000
	opsfileHTTPS := `---
# Configure HTTP2
- type: replace
  path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/enable_http2?
  value: ((enable_http2))
# Configure CA and cert chain
- type: replace
  path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/crt_list?/-
  value:
    snifilter:
    - haproxy.internal
    ssl_pem:
      cert_chain: ((https_frontend.certificate))((https_frontend_ca.certificate))
      private_key: ((https_frontend.private_key))
# Declare certs
- type: replace
  path: /variables?/-
  value:
    name: https_frontend_ca
    type: certificate
    options:
      is_ca: true
      common_name: bosh
- type: replace
  path: /variables?/-
  value:
    name: https_frontend
    type: certificate
    options:
      ca: https_frontend_ca
      common_name: haproxy.internal
      alternative_names: [haproxy.internal]
`

	var creds struct {
		HTTPSFrontend struct {
			Certificate string `yaml:"certificate"`
			PrivateKey  string `yaml:"private_key"`
			CA          string `yaml:"ca"`
		} `yaml:"https_frontend"`
	}

	JustBeforeEach(func() {
		var varsStoreReader varsStoreReader
		haproxyInfo, varsStoreReader = deployHAProxy(baseManifestVars{
			haproxyBackendPort:    haproxyBackendPort,
			haproxyBackendServers: []string{"127.0.0.1"},
			deploymentName:        defaultDeploymentName,
		}, []string{opsfileHTTPS}, map[string]interface{}{
			"enable_http2": enableHTTP2,
		}, true)

		err := varsStoreReader(&creds)
		Expect(err).NotTo(HaveOccurred())

		var localPort int
		closeLocalServer, localPort = startDefaultTestServer()
		closeTunnel = setupTunnelFromHaproxyToTestServer(haproxyInfo, haproxyBackendPort, localPort)

		http1Client = buildHTTPClient(
			[]string{creds.HTTPSFrontend.CA},
			map[string]string{"haproxy.internal:443": fmt.Sprintf("%s:443", haproxyInfo.PublicIP)},
			[]tls.Certificate{}, "",
		)
	})

	AfterEach(func() {
		if closeLocalServer != nil {
			defer closeLocalServer()
		}
		if closeTunnel != nil {
			defer closeTunnel()
		}
	})

	It("Correctly proxies HTTPS requests", func() {
		By("Sending a request to HAProxy using HTTP 1.1")
		resp, err := http1Client.Get("https://haproxy.internal:443")
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.ProtoMajor).To(Equal(1))

		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))
	})

	Context("When ha_proxy.enable_http2 is true", func() {
		BeforeEach(func() {
			enableHTTP2 = true
		})

		It("Allows clients to use HTTP2 as well as HTTP1.1", func() {
			By("Sending a request to HAProxy using HTTP 1.1")
			resp, err := http1Client.Get("https://haproxy.internal:443")
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.ProtoMajor).To(Equal(1))

			Expect(resp.StatusCode).To(Equal(http.StatusOK))
			Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))

			http2Client := buildHTTP2Client(
				[]string{creds.HTTPSFrontend.CA},
				map[string]string{"haproxy.internal:443": fmt.Sprintf("%s:443", haproxyInfo.PublicIP)},
				[]tls.Certificate{},
			)

			By("Sending a request to HAProxy using HTTP 2")
			resp, err = http2Client.Get("https://haproxy.internal:443")
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.ProtoMajor).To(Equal(2))

			Expect(resp.StatusCode).To(Equal(http.StatusOK))
			Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))
		})
	})
})
<commit_msg>adapt acceptance test to check for TLSv1.2 and 1.3<commit_after>package acceptance_tests

import (
	"crypto/tls"
	"fmt"
	"net/http"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
)

var _ = Describe("HTTPS Frontend", func() {
	var haproxyInfo haproxyInfo
	var closeTunnel func()
	var closeLocalServer func()
	enableHTTP2 := false
	var http1Client *http.Client

	haproxyBackendPort := 12000
	opsfileHTTPS := `---
# Configure HTTP2
- type: replace
  path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/enable_http2?
  value: ((enable_http2))
# Configure CA and cert chain
- type: replace
  path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/crt_list?/-
  value:
    snifilter:
    - haproxy.internal
    ssl_pem:
      cert_chain: ((https_frontend.certificate))((https_frontend_ca.certificate))
      private_key: ((https_frontend.private_key))
# Declare certs
- type: replace
  path: /variables?/-
  value:
    name: https_frontend_ca
    type: certificate
    options:
      is_ca: true
      common_name: bosh
- type: replace
  path: /variables?/-
  value:
    name: https_frontend
    type: certificate
    options:
      ca: https_frontend_ca
      common_name: haproxy.internal
      alternative_names: [haproxy.internal]
`

	var creds struct {
		HTTPSFrontend struct {
			Certificate string `yaml:"certificate"`
			PrivateKey  string `yaml:"private_key"`
			CA          string `yaml:"ca"`
		} `yaml:"https_frontend"`
	}

	JustBeforeEach(func() {
		var varsStoreReader varsStoreReader
		haproxyInfo, varsStoreReader = deployHAProxy(baseManifestVars{
			haproxyBackendPort:    haproxyBackendPort,
			haproxyBackendServers: []string{"127.0.0.1"},
			deploymentName:        defaultDeploymentName,
		}, []string{opsfileHTTPS}, map[string]interface{}{
			"enable_http2": enableHTTP2,
		}, true)

		err := varsStoreReader(&creds)
		Expect(err).NotTo(HaveOccurred())

		var localPort int
		closeLocalServer, localPort = startDefaultTestServer()
		closeTunnel = setupTunnelFromHaproxyToTestServer(haproxyInfo, haproxyBackendPort, localPort)

		http1Client = buildHTTPClient(
			[]string{creds.HTTPSFrontend.CA},
			map[string]string{"haproxy.internal:443": fmt.Sprintf("%s:443", haproxyInfo.PublicIP)},
			[]tls.Certificate{}, "",
		)
	})

	AfterEach(func() {
		if closeLocalServer != nil {
			defer closeLocalServer()
		}
		if closeTunnel != nil {
			defer closeTunnel()
		}
	})

	It("Correctly proxies HTTPS requests with TLSv1.2 and 1.3", func() {
		By("Sending a request to HAProxy using HTTP 1.1 and TLSv1.2")

		http1Client.Transport.(*http.Transport).TLSClientConfig.MaxVersion = tls.VersionTLS12
		http1Client.Transport.(*http.Transport).TLSClientConfig.MinVersion = tls.VersionTLS12

		resp, err := http1Client.Get("https://haproxy.internal:443")
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.ProtoMajor).To(Equal(1))

		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))

		By("Sending a request to HAProxy using HTTP 1.1 and TLSv1.3")

		http1Client.Transport.(*http.Transport).TLSClientConfig.MaxVersion = tls.VersionTLS13
		http1Client.Transport.(*http.Transport).TLSClientConfig.MinVersion = tls.VersionTLS13

		resp, err = http1Client.Get("https://haproxy.internal:443")
		Expect(err).NotTo(HaveOccurred())
		Expect(resp.ProtoMajor).To(Equal(1))

		Expect(resp.StatusCode).To(Equal(http.StatusOK))
		Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))
	})

	Context("When ha_proxy.enable_http2 is true", func() {
		BeforeEach(func() {
			enableHTTP2 = true
		})

		It("Allows clients to use HTTP2 as well as HTTP1.1", func() {
			By("Sending a request to HAProxy using HTTP 1.1")
			resp, err := http1Client.Get("https://haproxy.internal:443")
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.ProtoMajor).To(Equal(1))

			Expect(resp.StatusCode).To(Equal(http.StatusOK))
			Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))

			http2Client := buildHTTP2Client(
				[]string{creds.HTTPSFrontend.CA},
				map[string]string{"haproxy.internal:443": fmt.Sprintf("%s:443", haproxyInfo.PublicIP)},
				[]tls.Certificate{},
			)

			By("Sending a request to HAProxy using HTTP 2")
			resp, err = http2Client.Get("https://haproxy.internal:443")
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.ProtoMajor).To(Equal(2))

			Expect(resp.StatusCode).To(Equal(http.StatusOK))
			Eventually(gbytes.BufferReader(resp.Body)).Should(gbytes.Say("Hello cloud foundry"))
		})
	})
})
<|endoftext|>