func ResolveDepValuesForZone(app string, zkEnv *datamodel.ZkEnv, zone string, names []string, encrypt bool, t *Task) (DepsType, error) { var ( err error suffix string ) deps := DepsType{} // if we're using DNS and the app is registered, try to get the app cname (if deployed) if dns.Provider != nil { suffix, err = dns.Provider.Suffix(Region) if err != nil { return deps, err } } for _, name := range names { // if app is registered for this dependency name zkApp, err := datamodel.GetApp(name) if err != nil { continue } appEnvData := zkApp.GetDependerEnvDataForDependerApp(app, zkEnv.Name, true) if appEnvData == nil { continue } envData := zkApp.GetDependerEnvData(zkEnv.Name, true) if envData == nil { envData = &DependerEnvData{Name: appEnvData.Name} } // merge the data mergedEnvData := MergeDependerEnvData(envData, appEnvData) appDep := &AppDep{ SecurityGroup: mergedEnvData.SecurityGroup, DataMap: mergedEnvData.DataMap, } if dns.Provider != nil && !zkApp.NonAtlantis && zkApp.Internal { // auto-populate Address port, created, err := datamodel.ReserveRouterPortAndUpdateTrie(zkApp.Internal, name, "", zkEnv.Name) if err != nil { return deps, err } if created { // add warning since this means that the app has not been deployed in this env yet t.AddWarning("App dependency " + name + " has not yet been deployed in environment " + zkEnv.Name) } if appDep.DataMap == nil { appDep.DataMap = map[string]interface{}{} } appDep.DataMap["address"] = helper.GetZoneRouterCName(true, zone, suffix) + ":" + port // auto-populate SecurityGroup portUint, err := strconv.ParseUint(port, 10, 16) if err != nil { return deps, err } appDep.SecurityGroup = map[string][]uint16{netsec.InternalRouterIPGroup: []uint16{uint16(portUint)}} } deps[name] = appDep } if encrypt { for _, value := range deps { crypto.EncryptAppDep(value) } } for _, name := range names { if _, ok := deps[name]; !ok { return deps, errors.New("Could not resolve dep " + name) } } return deps, nil }
func deployToHostsInZones(deps map[string]DepsType, manifest *Manifest, sha, env string, hosts map[string][]string, zones []string, t *Task) ([]*Container, error) { deployedContainers := []*Container{} // fetch the app zkApp, err := datamodel.GetApp(manifest.Name) if err != nil { return nil, err } // first check if zones have enough hosts for _, zone := range zones { // fail if zone has no hosts if hosts[zone] == nil || len(hosts[zone]) == 0 { return nil, errors.New(fmt.Sprintf("No hosts available for app %s in zone %s", manifest.Name, zone)) } } // now that we know that enough hosts are available t.LogStatus("Deploying to zones: %v", zones) respCh := make(chan *DeployZoneResult, len(zones)) for _, zone := range zones { go deployToZone(respCh, deps, manifest, sha, env, hosts[zone], zone) } numResults := 0 status := "Deployed to zones: " for result := range respCh { deployedContainers = append(deployedContainers, result.Containers...) if result.Error != nil { err = result.Error t.Log(err.Error()) status += result.Zone + ":FAIL " } else { status += result.Zone + ":SUCCESS " } t.LogStatus(status) numResults++ if numResults >= len(zones) { // we're done close(respCh) } } if err != nil { cleanup(false, deployedContainers, t) return nil, err } // set ports on zk supervisor - can't do this in parallel. we may deploy to the same host at the same time // and since we don't lock zookeeper (maybe we should), this would result in a race condition. t.LogStatus("Updating Zookeeper") for _, cont := range deployedContainers { datamodel.Supervisor(cont.Host).SetContainerAndPort(cont.ID, cont.PrimaryPort) } // we're good now, so lets move on t.LogStatus("Updating Router") deployedIDs := make([]string, len(deployedContainers)) count := 0 for _, cont := range deployedContainers { deployedIDs[count] = cont.ID count++ } err = datamodel.AddToPool(deployedIDs) if err != nil { // if we can't add the pool, clean up and fail cleanup(true, deployedContainers, t) return nil, errors.New("Update Pool Error: " + err.Error()) } if zkApp.Internal { // reserve router port if needed and add app+env _, _, err = datamodel.ReserveRouterPortAndUpdateTrie(zkApp.Internal, manifest.Name, sha, env) if err != nil { datamodel.DeleteFromPool(deployedIDs) cleanup(true, deployedContainers, t) return nil, errors.New("Reserve Router Port Error: " + err.Error()) } } else { // only update trie _, err = datamodel.UpdateAppEnvTrie(zkApp.Internal, manifest.Name, sha, env) if err != nil { datamodel.DeleteFromPool(deployedIDs) cleanup(true, deployedContainers, t) return nil, errors.New("Reserve Router Port Error: " + err.Error()) } } return deployedContainers, nil }