github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/actor/pushaction/application_config.go (about)

     1  package pushaction
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  
     7  	"code.cloudfoundry.org/cli/actor/sharedaction"
     8  	"code.cloudfoundry.org/cli/actor/v2action"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
    10  	"code.cloudfoundry.org/cli/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  }