作者:adevendr
项目:atlantis-manage
func CreateRouterPaths() {
helper.SetRouterRoot(true)
for _, path := range routerzk.ZkPaths {
Zk.Touch(path)
}
helper.SetRouterRoot(false)
for _, path := range routerzk.ZkPaths {
Zk.Touch(path)
}
for _, zone := range AvailableZones {
Zk.Touch(helper.GetBaseRouterPath(true, zone))
Zk.Touch(helper.GetBaseRouterPath(false, zone))
}
}
作者:irregula
项目:atlantis-manage
func ReserveRouterPortAndUpdateTrie(internal bool, app, sha, env string) (string, bool, error) {
helper.SetRouterRoot(internal)
var (
err error
created = false
port = ""
trieName = ""
)
// reserve port for app env
if !HasRouterPortForAppEnv(internal, app, env) {
created = true
}
if port, err = reserveRouterPort(internal, app, env); err != nil {
return port, created, err
}
if trieName, err = UpdateAppEnvTrie(internal, app, sha, env); err != nil {
return port, created, err
}
// now port is reserved and trie is created so we can actually create port for router
portUInt, err := strconv.ParseUint(port, 10, 16)
if err != nil {
return port, created, err
}
err = routerzk.SetPort(Zk.Conn, routercfg.Port{
Port: uint16(portUInt),
Trie: trieName,
})
if err != nil {
return port, created, err
}
// return true if port was created
return port, created, err
}
作者:budhr
项目:atlantis-manage
func (e *GetAppEnvPortExecutor) Execute(t *Task) (err error) {
if e.arg.App == "" {
return errors.New("Please specify an app")
} else if e.arg.Env == "" {
return errors.New("Please specify an environment")
}
zkApp, err := datamodel.GetApp(e.arg.App)
if err != nil {
return err
}
zrp := datamodel.GetRouterPorts(zkApp.Internal)
fmt.Printf("ROUTER PORTS: %+v\n", zrp)
portStr := zrp.AppEnvMap[helper.GetAppEnvTrieName(e.arg.App, e.arg.Env)]
if portStr == "" {
return errors.New("port not found")
}
fmt.Printf("PORT STRING: %+v -> %+v\n", helper.GetAppEnvTrieName(e.arg.App, e.arg.Env), portStr)
port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
return err
}
helper.SetRouterRoot(zkApp.Internal)
e.reply.Port, err = routerzk.GetPort(datamodel.Zk.Conn, uint16(port))
return err
}
作者:irregula
项目:atlantis-manage
func (s *DatamodelSuite) TestReserveRouterPortAndUpdateTrie(c *C) {
Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(true))
Zk.RecursiveDelete(helper.GetBaseRouterPortsPath(false))
Zk.RecursiveDelete(helper.GetBaseLockPath())
Zk.RecursiveDelete("/atlantis/router")
CreateRouterPaths()
CreateRouterPortsPaths()
CreateLockPaths()
MinRouterPort = uint16(65533)
MaxRouterPort = uint16(65535)
helper.SetRouterRoot(true)
port, created, err := ReserveRouterPortAndUpdateTrie(true, "app", "sha", "env")
c.Assert(err, IsNil)
c.Assert(created, Equals, true)
c.Assert(port, Equals, "65533")
trie, err := routerzk.GetTrie(Zk.Conn, helper.GetAppEnvTrieName("app", "env"))
c.Assert(err, IsNil)
c.Assert(len(trie.Rules), Equals, 1)
port, created, err = ReserveRouterPortAndUpdateTrie(true, "app", "sha2", "env")
c.Assert(err, IsNil)
c.Assert(created, Equals, false)
c.Assert(port, Equals, "65533")
trie, err = routerzk.GetTrie(Zk.Conn, helper.GetAppEnvTrieName("app", "env"))
c.Assert(err, IsNil)
c.Assert(len(trie.Rules), Equals, 2)
}
作者:irregula
项目:atlantis-manage
func CleanupCreatedPoolRefs(internal bool, app, sha, env string) error {
helper.SetRouterRoot(internal)
// remove static rule, cleanup rule from trie if needed
ruleName := helper.GetAppShaEnvStaticRuleName(app, sha, env)
trieName := helper.GetAppEnvTrieName(app, env)
// remove static rule from trie
trie, err := routerzk.GetTrie(Zk.Conn, trieName)
if err != nil {
return err
}
newRules := []string{}
for _, rule := range trie.Rules {
if rule != ruleName {
newRules = append(newRules, rule)
}
}
if len(trie.Rules) != len(newRules) {
trie.Rules = newRules
err = routerzk.SetTrie(Zk.Conn, trie)
if err != nil {
return err
}
}
// delete static rule
err = routerzk.DelRule(Zk.Conn, ruleName)
if err != nil {
return err
}
return nil
}
作者:irregula
项目:atlantis-manage
func DeleteFromPool(containers []string) error {
pools := map[bool]map[string]*poolDefinition{}
pools[true] = map[string]*poolDefinition{}
pools[false] = map[string]*poolDefinition{}
for _, cont := range containers {
inst, err := GetInstance(cont)
if err != nil {
// instance doesn't exist
continue
}
name := helper.CreatePoolName(inst.App, inst.Sha, inst.Env)
zkApp, err := GetApp(inst.App)
if err != nil {
return err
}
poolDef := pools[zkApp.Internal][name]
if poolDef == nil {
poolDef = &poolDefinition{
app: inst.App,
sha: inst.Sha,
env: inst.Env,
insts: []*ZkInstance{},
}
pools[zkApp.Internal][name] = poolDef
}
pools[zkApp.Internal][name].insts = append(poolDef.insts, inst)
}
for internal, allPools := range pools {
helper.SetRouterRoot(internal)
for name, poolDef := range allPools {
// remove hosts
hosts := []string{}
for _, inst := range poolDef.insts {
hosts = append(hosts, fmt.Sprintf("%s:%d", inst.Host, inst.Port))
}
routerzk.DelHosts(Zk.Conn, name, hosts)
// delete pool if no hosts exist
getHosts, err := routerzk.GetHosts(Zk.Conn, name)
if err != nil || len(getHosts) == 0 {
err = routerzk.DelPool(Zk.Conn, name)
if err != nil {
log.Println("Error trying to clean up pool:", err)
}
err = CleanupCreatedPoolRefs(internal, poolDef.app, poolDef.sha, poolDef.env)
if err != nil {
log.Println("Error trying to clean up pool:", err)
}
}
}
}
return nil
}
作者:irregula
项目:atlantis-manage
func UpdateAppEnvTrie(internal bool, app, sha, env string) (string, error) {
helper.SetRouterRoot(internal)
// create trie (if it doesn't exist)
trieName := helper.GetAppEnvTrieName(app, env)
if exists, err := routerzk.TrieExists(Zk.Conn, trieName); !exists || err != nil {
err = routerzk.SetTrie(Zk.Conn, routercfg.Trie{
Name: trieName,
Rules: []string{},
Internal: internal,
})
if err != nil {
return trieName, err
}
}
// if sha != "" attach pool as static rule (if trie is empty)
if sha != "" {
// if static rule does not exist, create it
ruleName := helper.GetAppShaEnvStaticRuleName(app, sha, env)
poolName := helper.CreatePoolName(app, sha, env)
if exists, err := routerzk.RuleExists(Zk.Conn, ruleName); !exists || err != nil {
err = routerzk.SetRule(Zk.Conn, routercfg.Rule{
Name: ruleName,
Type: "static",
Value: "true",
Pool: poolName,
Internal: internal,
})
if err != nil {
return trieName, err
}
}
trie, err := routerzk.GetTrie(Zk.Conn, trieName)
if err != nil {
return trieName, err
}
if len(trie.Rules) == 0 {
trie.Rules = []string{ruleName}
} else {
trie.Rules = append(trie.Rules, ruleName)
}
if err = routerzk.SetTrie(Zk.Conn, trie); err != nil {
return trieName, err
}
}
return trieName, nil
}
作者:irregula
项目:atlantis-manage
func ReclaimRouterPortsForEnv(internal bool, env string) error {
helper.SetRouterRoot(internal)
lock := NewRouterPortsLock(internal)
lock.Lock()
defer lock.Unlock()
zrp := GetRouterPorts(internal)
ports, err := zrp.reclaimEnv(env)
if err != nil {
return err
}
for _, port := range ports {
if err := routerzk.DelPort(Zk.Conn, port); err != nil {
log.Printf("Error reclaiming port %d for env %s", port, env)
// don't fail here
// TODO email appsplat
}
}
return nil
}
作者:irregula
项目:atlantis-manage
func AddToPool(containers []string) error {
pools := map[bool]map[string][]*ZkInstance{}
pools[true] = map[string][]*ZkInstance{}
pools[false] = map[string][]*ZkInstance{}
for _, cont := range containers {
inst, err := GetInstance(cont)
if err != nil {
// instance doesn't exist
continue
}
name := helper.CreatePoolName(inst.App, inst.Sha, inst.Env)
zkApp, err := GetApp(inst.App)
if err != nil {
return err
}
currInsts := pools[zkApp.Internal][name]
if currInsts == nil {
currInsts = []*ZkInstance{}
}
pools[zkApp.Internal][name] = append(currInsts, inst)
}
for internal, allPools := range pools {
helper.SetRouterRoot(internal)
for name, insts := range allPools {
// create pool if we need to
if exists, err := routerzk.PoolExists(Zk.Conn, name); !exists || err != nil {
if err = routerzk.SetPool(Zk.Conn, defaultPool(name, internal)); err != nil {
return err
}
}
// add hosts
hosts := map[string]routercfg.Host{}
for _, inst := range insts {
address := fmt.Sprintf("%s:%d", inst.Host, inst.Port)
hosts[address] = routercfg.Host{Address: address}
}
if err := routerzk.AddHosts(Zk.Conn, name, hosts); err != nil {
return err
}
}
}
return nil
}
作者:irregula
项目:atlantis-manage
func (s *DatamodelSuite) TestRouterExternalPool(c *C) {
Zk.RecursiveDelete("/atlantis/router")
Zk.RecursiveDelete("/atlantis/apps")
Zk.RecursiveDelete(helper.GetBaseInstancePath())
CreateRouterPaths()
CreateAppPath()
// fake register app
CreateOrUpdateApp(false, false, app, "ssh://[email protected]/app", "/", "[email protected]")
CreateOrUpdateApp(false, false, "app2", "ssh://[email protected]/app", "/", "[email protected]")
// do tests
instance, err := CreateInstance(app, sha, env, host+"-1")
c.Assert(err, IsNil)
instance.SetPort(uint16(1337))
instance2, err := CreateInstance(app, sha, env, host+"-2")
c.Assert(err, IsNil)
instance2.SetPort(uint16(1338))
c.Assert(AddToPool([]string{instance.ID, instance2.ID}), IsNil)
theName := helper.CreatePoolName(app, sha, env)
helper.SetRouterRoot(false)
thePool, err := routerzk.GetPool(Zk.Conn, theName)
c.Assert(err, IsNil)
c.Assert(thePool.Name, Equals, theName)
c.Assert(thePool.Config.HealthzEvery, Not(Equals), "")
c.Assert(thePool.Config.HealthzTimeout, Not(Equals), "")
c.Assert(thePool.Config.RequestTimeout, Not(Equals), "")
c.Assert(thePool.Hosts, DeepEquals, map[string]config.Host{host + "-1:1337": config.Host{Address: host + "-1:1337"}, host + "-2:1338": config.Host{Address: host + "-2:1338"}})
newInstance, err := CreateInstance("app2", "sha1", "env1", host+"-1")
c.Assert(err, IsNil)
newInstance.SetPort(uint16(1339))
newInstance2, err := CreateInstance(app, sha, env, host+"-3")
c.Assert(err, IsNil)
newInstance2.SetPort(uint16(1340))
c.Assert(DeleteFromPool([]string{instance2.ID}), IsNil)
instance2.Delete()
c.Assert(AddToPool([]string{newInstance.ID, newInstance2.ID}), IsNil)
helper.SetRouterRoot(false)
thePool, err = routerzk.GetPool(Zk.Conn, theName)
c.Assert(err, IsNil)
c.Assert(thePool.Name, Equals, theName)
c.Assert(thePool.Config.HealthzEvery, Not(Equals), "")
c.Assert(thePool.Config.HealthzTimeout, Not(Equals), "")
c.Assert(thePool.Config.RequestTimeout, Not(Equals), "")
c.Assert(thePool.Hosts, DeepEquals, map[string]config.Host{host + "-1:1337": config.Host{Address: host + "-1:1337"}, host + "-3:1340": config.Host{Address: host + "-3:1340"}})
helper.SetRouterRoot(false)
thePool2, err := routerzk.GetPool(Zk.Conn, helper.CreatePoolName("app2", "sha1", "env1"))
c.Assert(err, IsNil)
c.Assert(thePool2.Name, Equals, helper.CreatePoolName("app2", "sha1", "env1"))
c.Assert(thePool2.Config.HealthzEvery, Not(Equals), "")
c.Assert(thePool2.Config.HealthzTimeout, Not(Equals), "")
c.Assert(thePool2.Config.RequestTimeout, Not(Equals), "")
c.Assert(thePool2.Hosts, DeepEquals, map[string]config.Host{host + "-1:1339": config.Host{Address: host + "-1:1339"}})
helper.SetRouterRoot(false)
pools, err := routerzk.ListPools(Zk.Conn)
c.Assert(err, IsNil)
sort.Strings(pools)
c.Assert(pools, DeepEquals, []string{thePool2.Name, thePool.Name})
c.Assert(DeleteFromPool([]string{instance.ID, newInstance.ID, newInstance2.ID}), IsNil)
instance.Delete()
newInstance.Delete()
newInstance2.Delete()
helper.SetRouterRoot(false)
thePool, err = routerzk.GetPool(Zk.Conn, theName)
c.Assert(err, Not(IsNil))
}