github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+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 app.Command != "" { 126 cmd.manifest.StartCommand(app.Name, app.Command) 127 } 128 129 if app.BuildpackURL != "" { 130 cmd.manifest.BuildpackURL(app.Name, app.BuildpackURL) 131 } 132 133 if len(app.Services) > 0 { 134 for _, service := range app.Services { 135 cmd.manifest.Service(app.Name, service.Name) 136 } 137 } 138 139 if app.HealthCheckTimeout > 0 { 140 cmd.manifest.HealthCheckTimeout(app.Name, app.HealthCheckTimeout) 141 } 142 143 if app.HealthCheckType != "port" { 144 cmd.manifest.HealthCheckType(app.Name, app.HealthCheckType) 145 } 146 147 if app.HealthCheckType == "http" && 148 app.HealthCheckHTTPEndpoint != "" && 149 app.HealthCheckHTTPEndpoint != "/" { 150 cmd.manifest.HealthCheckHTTPEndpoint(app.Name, app.HealthCheckHTTPEndpoint) 151 } 152 153 if len(app.EnvironmentVars) > 0 { 154 sorted := sortEnvVar(app.EnvironmentVars) 155 for _, envVarKey := range sorted { 156 switch app.EnvironmentVars[envVarKey].(type) { 157 default: 158 return errors.New(T("Failed to create manifest, unable to parse environment variable: ") + envVarKey) 159 case float64: 160 //json.Unmarshal turn all numbers to float64 161 value := int(app.EnvironmentVars[envVarKey].(float64)) 162 cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%d", value)) 163 case bool: 164 cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%t", app.EnvironmentVars[envVarKey].(bool))) 165 case string: 166 cmd.manifest.EnvironmentVars(app.Name, envVarKey, app.EnvironmentVars[envVarKey].(string)) 167 } 168 } 169 } 170 171 if len(app.Routes) > 0 { 172 for i := 0; i < len(app.Routes); i++ { 173 cmd.manifest.Route(app.Name, app.Routes[i].Host, app.Routes[i].Domain.Name, app.Routes[i].Path, app.Routes[i].Port) 174 } 175 } 176 177 if app.DiskQuota != 0 { 178 cmd.manifest.DiskQuota(app.Name, app.DiskQuota) 179 } 180 181 return nil 182 } 183 184 func sortEnvVar(vars map[string]interface{}) []string { 185 var varsAry []string 186 for k := range vars { 187 varsAry = append(varsAry, k) 188 } 189 sort.Strings(varsAry) 190 191 return varsAry 192 }