github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/commands/create_app_manifest.go (about) 1 package commands 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "sort" 8 9 "code.cloudfoundry.org/cli/cf/flags" 10 . "code.cloudfoundry.org/cli/cf/i18n" 11 12 "code.cloudfoundry.org/cli/cf/api" 13 "code.cloudfoundry.org/cli/cf/api/appinstances" 14 "code.cloudfoundry.org/cli/cf/api/stacks" 15 "code.cloudfoundry.org/cli/cf/commandregistry" 16 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 17 "code.cloudfoundry.org/cli/cf/manifest" 18 "code.cloudfoundry.org/cli/cf/models" 19 "code.cloudfoundry.org/cli/cf/requirements" 20 "code.cloudfoundry.org/cli/cf/terminal" 21 ) 22 23 type CreateAppManifest struct { 24 ui terminal.UI 25 config coreconfig.Reader 26 appSummaryRepo api.AppSummaryRepository 27 stackRepo stacks.StackRepository 28 appInstancesRepo appinstances.Repository 29 appReq requirements.ApplicationRequirement 30 manifest manifest.App 31 } 32 33 func init() { 34 commandregistry.Register(&CreateAppManifest{}) 35 } 36 37 func (cmd *CreateAppManifest) MetaData() commandregistry.CommandMetadata { 38 fs := make(map[string]flags.FlagSet) 39 fs["p"] = &flags.StringFlag{ShortName: "p", Usage: T("Specify a path for file creation. If path not specified, manifest file is created in current working directory.")} 40 41 return commandregistry.CommandMetadata{ 42 Name: "create-app-manifest", 43 Description: T("Create an app manifest for an app that has been pushed successfully"), 44 Usage: []string{ 45 T("CF_NAME create-app-manifest APP_NAME [-p /path/to/<app-name>-manifest.yml ]"), 46 }, 47 Flags: fs, 48 } 49 } 50 51 func (cmd *CreateAppManifest) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) { 52 if len(fc.Args()) != 1 { 53 cmd.ui.Failed(T("Incorrect Usage. Requires APP_NAME as argument\n\n") + commandregistry.Commands.CommandUsage("create-app-manifest")) 54 return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 1) 55 } 56 57 cmd.appReq = requirementsFactory.NewApplicationRequirement(fc.Args()[0]) 58 59 reqs := []requirements.Requirement{ 60 requirementsFactory.NewLoginRequirement(), 61 requirementsFactory.NewTargetedSpaceRequirement(), 62 cmd.appReq, 63 } 64 65 return reqs, nil 66 } 67 68 func (cmd *CreateAppManifest) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command { 69 cmd.ui = deps.UI 70 cmd.config = deps.Config 71 cmd.appSummaryRepo = deps.RepoLocator.GetAppSummaryRepository() 72 cmd.stackRepo = deps.RepoLocator.GetStackRepository() 73 cmd.manifest = deps.AppManifest 74 return cmd 75 } 76 77 func (cmd *CreateAppManifest) Execute(c flags.FlagContext) error { 78 application, apiErr := cmd.appSummaryRepo.GetSummary(cmd.appReq.GetApplication().GUID) 79 if apiErr != nil { 80 return errors.New(T("Error getting application summary: ") + apiErr.Error()) 81 } 82 83 stack, err := cmd.stackRepo.FindByGUID(application.StackGUID) 84 if err != nil { 85 return errors.New(T("Error retrieving stack: ") + err.Error()) 86 } 87 88 application.Stack = &stack 89 90 cmd.ui.Say(T("Creating an app manifest from current settings of app ") + application.Name + " ...") 91 cmd.ui.Say("") 92 93 savePath := "./" + application.Name + "_manifest.yml" 94 95 if c.String("p") != "" { 96 savePath = c.String("p") 97 } 98 99 f, err := os.Create(savePath) 100 if err != nil { 101 return errors.New(T("Error creating manifest file: ") + err.Error()) 102 } 103 defer f.Close() 104 105 err = cmd.createManifest(application) 106 if err != nil { 107 return err 108 } 109 err = cmd.manifest.Save(f) 110 if err != nil { 111 return errors.New(T("Error creating manifest file: ") + err.Error()) 112 } 113 114 cmd.ui.Ok() 115 cmd.ui.Say(T("Manifest file created successfully at ") + savePath) 116 cmd.ui.Say("") 117 return nil 118 } 119 120 func (cmd *CreateAppManifest) createManifest(app models.Application) error { 121 cmd.manifest.Memory(app.Name, app.Memory) 122 cmd.manifest.Instances(app.Name, app.InstanceCount) 123 cmd.manifest.Stack(app.Name, app.Stack.Name) 124 125 if len(app.AppPorts) > 0 { 126 cmd.manifest.AppPorts(app.Name, app.AppPorts) 127 } 128 129 if app.Command != "" { 130 cmd.manifest.StartCommand(app.Name, app.Command) 131 } 132 133 if app.BuildpackURL != "" { 134 cmd.manifest.BuildpackURL(app.Name, app.BuildpackURL) 135 } 136 137 if len(app.Services) > 0 { 138 for _, service := range app.Services { 139 cmd.manifest.Service(app.Name, service.Name) 140 } 141 } 142 143 if app.HealthCheckTimeout > 0 { 144 cmd.manifest.HealthCheckTimeout(app.Name, app.HealthCheckTimeout) 145 } 146 147 if app.HealthCheckType != "port" { 148 cmd.manifest.HealthCheckType(app.Name, app.HealthCheckType) 149 } 150 151 if app.HealthCheckType == "http" && 152 app.HealthCheckHTTPEndpoint != "" && 153 app.HealthCheckHTTPEndpoint != "/" { 154 cmd.manifest.HealthCheckHTTPEndpoint(app.Name, app.HealthCheckHTTPEndpoint) 155 } 156 157 if len(app.EnvironmentVars) > 0 { 158 sorted := sortEnvVar(app.EnvironmentVars) 159 for _, envVarKey := range sorted { 160 switch app.EnvironmentVars[envVarKey].(type) { 161 default: 162 return errors.New(T("Failed to create manifest, unable to parse environment variable: ") + envVarKey) 163 case float64: 164 //json.Unmarshal turn all numbers to float64 165 value := int(app.EnvironmentVars[envVarKey].(float64)) 166 cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%d", value)) 167 case bool: 168 cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%t", app.EnvironmentVars[envVarKey].(bool))) 169 case string: 170 cmd.manifest.EnvironmentVars(app.Name, envVarKey, app.EnvironmentVars[envVarKey].(string)) 171 } 172 } 173 } 174 175 if len(app.Routes) > 0 { 176 for i := 0; i < len(app.Routes); i++ { 177 cmd.manifest.Route(app.Name, app.Routes[i].Host, app.Routes[i].Domain.Name, app.Routes[i].Path, app.Routes[i].Port) 178 } 179 } 180 181 if app.DiskQuota != 0 { 182 cmd.manifest.DiskQuota(app.Name, app.DiskQuota) 183 } 184 185 return nil 186 } 187 188 func sortEnvVar(vars map[string]interface{}) []string { 189 var varsAry []string 190 for k := range vars { 191 varsAry = append(varsAry, k) 192 } 193 sort.Strings(varsAry) 194 195 return varsAry 196 }