github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/actor/pushaction/application_config.go (about) 1 package pushaction 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/liamawhite/cli-with-i18n/actor/sharedaction" 8 "github.com/liamawhite/cli-with-i18n/actor/v2action" 9 "github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccv2" 10 "github.com/liamawhite/cli-with-i18n/util/manifest" 11 log "github.com/Sirupsen/logrus" 12 ) 13 14 type ApplicationConfig struct { 15 CurrentApplication Application 16 DesiredApplication Application 17 18 CurrentRoutes []v2action.Route 19 DesiredRoutes []v2action.Route 20 21 CurrentServices map[string]v2action.ServiceInstance 22 DesiredServices map[string]v2action.ServiceInstance 23 24 AllResources []v2action.Resource 25 MatchedResources []v2action.Resource 26 UnmatchedResources []v2action.Resource 27 Archive bool 28 Path string 29 30 TargetedSpaceGUID string 31 } 32 33 func (config ApplicationConfig) CreatingApplication() bool { 34 return config.CurrentApplication.GUID == "" 35 } 36 37 func (config ApplicationConfig) UpdatingApplication() bool { 38 return !config.CreatingApplication() 39 } 40 41 func (actor Actor) ConvertToApplicationConfigs(orgGUID string, spaceGUID string, noStart bool, apps []manifest.Application) ([]ApplicationConfig, Warnings, error) { 42 var configs []ApplicationConfig 43 var warnings Warnings 44 45 log.Infof("iterating through %d app configuration(s)", len(apps)) 46 for _, app := range apps { 47 absPath, err := filepath.EvalSymlinks(app.Path) 48 if err != nil { 49 return nil, nil, err 50 } 51 52 config := ApplicationConfig{ 53 TargetedSpaceGUID: spaceGUID, 54 Path: absPath, 55 } 56 57 log.Infoln("searching for app", app.Name) 58 found, constructedApp, v2Warnings, err := actor.FindOrReturnPartialApp(app.Name, spaceGUID) 59 warnings = append(warnings, v2Warnings...) 60 if err != nil { 61 log.Errorln("app lookup:", err) 62 return nil, warnings, err 63 } 64 65 if found { 66 var configWarnings v2action.Warnings 67 config, configWarnings, err = actor.configureExistingApp(config, app, constructedApp) 68 warnings = append(warnings, configWarnings...) 69 if err != nil { 70 log.Errorln("configuring existing app:", err) 71 return nil, warnings, err 72 } 73 } else { 74 log.Debug("using empty app as base") 75 config.DesiredApplication = constructedApp 76 } 77 78 config.DesiredApplication = actor.overrideApplicationProperties(config.DesiredApplication, app, noStart) 79 80 var stackWarnings Warnings 81 config.DesiredApplication, stackWarnings, err = actor.overrideStack(config.DesiredApplication, app) 82 warnings = append(warnings, stackWarnings...) 83 if err != nil { 84 return nil, warnings, err 85 } 86 log.Debugln("post overriding config:", config.DesiredApplication) 87 88 var serviceWarnings Warnings 89 config.DesiredServices, serviceWarnings, err = actor.getDesiredServices(config.CurrentServices, app.Services, spaceGUID) 90 warnings = append(warnings, serviceWarnings...) 91 if err != nil { 92 log.Errorln("getting services:", err) 93 return nil, warnings, err 94 } 95 96 var routeWarnings Warnings 97 config, routeWarnings, err = actor.configureRoutes(app.Routes, orgGUID, spaceGUID, config) 98 warnings = append(warnings, routeWarnings...) 99 if err != nil { 100 log.Errorln("determining routes:", err) 101 return nil, warnings, err 102 } 103 104 config, err = actor.configureResources(config, app.DockerImage) 105 if err != nil { 106 log.Errorln("configuring resources", err) 107 return nil, warnings, err 108 } 109 110 configs = append(configs, config) 111 } 112 113 return configs, warnings, nil 114 } 115 116 func (actor Actor) configureRoutes(routesInManifest []string, orgGUID string, spaceGUID string, config ApplicationConfig) (ApplicationConfig, Warnings, error) { 117 if len(routesInManifest) > 0 { 118 var warnings Warnings 119 var err error 120 config.DesiredRoutes, warnings, err = actor.CalculateRoutes(routesInManifest, orgGUID, spaceGUID, config.CurrentRoutes) 121 return config, warnings, err 122 } 123 124 defaultRoute, warnings, err := actor.GetRouteWithDefaultDomain(config.DesiredApplication.Name, orgGUID, spaceGUID, config.CurrentRoutes) 125 if err != nil { 126 log.Errorln("getting default route:", err) 127 return config, warnings, err 128 } 129 130 // TODO: when working with all of routes, append to current route 131 config.DesiredRoutes = append(config.CurrentRoutes, defaultRoute) 132 return config, warnings, nil 133 } 134 135 func (actor Actor) getDesiredServices(currentServices map[string]v2action.ServiceInstance, requestedServices []string, spaceGUID string) (map[string]v2action.ServiceInstance, Warnings, error) { 136 var warnings Warnings 137 138 desiredServices := map[string]v2action.ServiceInstance{} 139 for name, serviceInstance := range currentServices { 140 log.Debugln("adding bound service:", name) 141 desiredServices[name] = serviceInstance 142 } 143 144 for _, serviceName := range requestedServices { 145 if _, ok := desiredServices[serviceName]; !ok { 146 log.Debugln("adding requested service:", serviceName) 147 serviceInstance, serviceWarnings, err := actor.V2Actor.GetServiceInstanceByNameAndSpace(serviceName, spaceGUID) 148 warnings = append(warnings, serviceWarnings...) 149 if err != nil { 150 return nil, warnings, err 151 } 152 153 desiredServices[serviceName] = serviceInstance 154 } 155 } 156 return desiredServices, warnings, nil 157 } 158 159 func (actor Actor) configureExistingApp(config ApplicationConfig, app manifest.Application, foundApp Application) (ApplicationConfig, v2action.Warnings, error) { 160 log.Debugln("found app:", foundApp) 161 config.CurrentApplication = foundApp 162 config.DesiredApplication = foundApp 163 164 log.Info("looking up application routes") 165 routes, warnings, err := actor.V2Actor.GetApplicationRoutes(foundApp.GUID) 166 if err != nil { 167 log.Errorln("existing routes lookup:", err) 168 return config, warnings, err 169 } 170 171 serviceInstances, serviceWarnings, err := actor.V2Actor.GetServiceInstancesByApplication(foundApp.GUID) 172 warnings = append(warnings, serviceWarnings...) 173 if err != nil { 174 log.Errorln("existing services lookup:", err) 175 return config, warnings, err 176 } 177 178 nameToService := map[string]v2action.ServiceInstance{} 179 for _, serviceInstance := range serviceInstances { 180 nameToService[serviceInstance.Name] = serviceInstance 181 } 182 183 config.CurrentRoutes = routes 184 config.CurrentServices = nameToService 185 return config, warnings, nil 186 } 187 188 func (actor Actor) configureResources(config ApplicationConfig, dockerImagePath string) (ApplicationConfig, error) { 189 if dockerImagePath == "" { 190 info, err := os.Stat(config.Path) 191 if err != nil { 192 return config, err 193 } 194 195 var resources []sharedaction.Resource 196 if info.IsDir() { 197 log.WithField("path_to_resources", config.Path).Info("determine directory resources to zip") 198 resources, err = actor.SharedActor.GatherDirectoryResources(config.Path) 199 } else { 200 config.Archive = true 201 log.WithField("path_to_resources", config.Path).Info("determine archive resources to zip") 202 resources, err = actor.SharedActor.GatherArchiveResources(config.Path) 203 } 204 if err != nil { 205 return config, err 206 } 207 config.AllResources = actor.ConvertSharedResourcesToV2Resources(resources) 208 209 log.WithField("number_of_files", len(resources)).Debug("completed file scan") 210 } 211 212 return config, nil 213 } 214 215 func (Actor) overrideApplicationProperties(application Application, manifest manifest.Application, noStart bool) Application { 216 if manifest.Buildpack.IsSet { 217 application.Buildpack = manifest.Buildpack 218 } 219 if manifest.Command.IsSet { 220 application.Command = manifest.Command 221 } 222 if manifest.DockerImage != "" { 223 application.DockerImage = manifest.DockerImage 224 if manifest.DockerUsername != "" { 225 application.DockerCredentials.Username = manifest.DockerUsername 226 application.DockerCredentials.Password = manifest.DockerPassword 227 } 228 } 229 230 if manifest.DiskQuota.IsSet { 231 application.DiskQuota = manifest.DiskQuota.Value 232 } 233 234 if manifest.Memory.IsSet { 235 application.Memory = manifest.Memory.Value 236 } 237 238 if manifest.HealthCheckHTTPEndpoint != "" { 239 application.HealthCheckHTTPEndpoint = manifest.HealthCheckHTTPEndpoint 240 } 241 if manifest.HealthCheckTimeout != 0 { 242 application.HealthCheckTimeout = manifest.HealthCheckTimeout 243 } 244 if manifest.HealthCheckType != "" { 245 application.HealthCheckType = ccv2.ApplicationHealthCheckType(manifest.HealthCheckType) 246 } 247 if manifest.Instances.IsSet { 248 application.Instances = manifest.Instances 249 } 250 251 if noStart { 252 application.State = ccv2.ApplicationStopped 253 } 254 255 if len(manifest.EnvironmentVariables) > 0 { 256 if application.EnvironmentVariables == nil { 257 application.EnvironmentVariables = manifest.EnvironmentVariables 258 } else { 259 env := map[string]string{} 260 for key, value := range application.EnvironmentVariables { 261 env[key] = value 262 } 263 for key, value := range manifest.EnvironmentVariables { 264 env[key] = value 265 } 266 application.EnvironmentVariables = env 267 } 268 } 269 270 log.Debugln("post application override:", application) 271 272 return application 273 } 274 275 func (actor Actor) overrideStack(application Application, manifest manifest.Application) (Application, Warnings, error) { 276 if manifest.StackName == "" { 277 return application, nil, nil 278 } 279 stack, warnings, err := actor.V2Actor.GetStackByName(manifest.StackName) 280 application.SetStack(stack) 281 return application, Warnings(warnings), err 282 }