github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/commands/create_app_manifest.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	. "github.com/cloudfoundry/cli/cf/i18n"
     8  	"github.com/cloudfoundry/cli/flags"
     9  	"github.com/cloudfoundry/cli/flags/flag"
    10  
    11  	"github.com/cloudfoundry/cli/cf/api"
    12  	"github.com/cloudfoundry/cli/cf/api/app_instances"
    13  	"github.com/cloudfoundry/cli/cf/command_registry"
    14  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    15  	"github.com/cloudfoundry/cli/cf/manifest"
    16  	"github.com/cloudfoundry/cli/cf/models"
    17  	"github.com/cloudfoundry/cli/cf/requirements"
    18  	"github.com/cloudfoundry/cli/cf/terminal"
    19  )
    20  
    21  type CreateAppManifest struct {
    22  	ui               terminal.UI
    23  	config           core_config.Reader
    24  	appSummaryRepo   api.AppSummaryRepository
    25  	appInstancesRepo app_instances.AppInstancesRepository
    26  	appReq           requirements.ApplicationRequirement
    27  	manifest         manifest.AppManifest
    28  }
    29  
    30  func init() {
    31  	command_registry.Register(&CreateAppManifest{})
    32  }
    33  
    34  func (cmd *CreateAppManifest) MetaData() command_registry.CommandMetadata {
    35  	fs := make(map[string]flags.FlagSet)
    36  	fs["p"] = &cliFlags.StringFlag{Name: "p", Usage: T("Specify a path for file creation. If path not specified, manifest file is created in current working directory.")}
    37  
    38  	return command_registry.CommandMetadata{
    39  		Name:        "create-app-manifest",
    40  		Description: T("Create an app manifest for an app that has been pushed successfully."),
    41  		Usage:       T("CF_NAME create-app-manifest APP_NAME [-p /path/to/<app-name>-manifest.yml ]"),
    42  		Flags:       fs,
    43  	}
    44  }
    45  
    46  func (cmd *CreateAppManifest) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) {
    47  	if len(fc.Args()) != 1 {
    48  		cmd.ui.Failed(T("Incorrect Usage. Requires APP_NAME as argument\n\n") + command_registry.Commands.CommandUsage("create-app-manifest"))
    49  	}
    50  
    51  	cmd.appReq = requirementsFactory.NewApplicationRequirement(fc.Args()[0])
    52  
    53  	reqs = []requirements.Requirement{
    54  		requirementsFactory.NewLoginRequirement(),
    55  		requirementsFactory.NewTargetedSpaceRequirement(),
    56  		cmd.appReq,
    57  	}
    58  	return
    59  }
    60  
    61  func (cmd *CreateAppManifest) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
    62  	cmd.ui = deps.Ui
    63  	cmd.config = deps.Config
    64  	cmd.appSummaryRepo = deps.RepoLocator.GetAppSummaryRepository()
    65  	cmd.manifest = deps.AppManifest
    66  	return cmd
    67  }
    68  
    69  func (cmd *CreateAppManifest) Execute(c flags.FlagContext) {
    70  	app := cmd.appReq.GetApplication()
    71  
    72  	application, apiErr := cmd.appSummaryRepo.GetSummary(app.Guid)
    73  	if apiErr != nil {
    74  		cmd.ui.Failed(T("Error getting application summary: ") + apiErr.Error())
    75  	}
    76  
    77  	cmd.ui.Say(T("Creating an app manifest from current settings of app ") + application.Name + " ...")
    78  	cmd.ui.Say("")
    79  
    80  	savePath := "./" + application.Name + "_manifest.yml"
    81  
    82  	if c.String("p") != "" {
    83  		savePath = c.String("p")
    84  	}
    85  
    86  	cmd.createManifest(application, savePath)
    87  }
    88  
    89  func (cmd *CreateAppManifest) createManifest(app models.Application, savePath string) error {
    90  	cmd.manifest.FileSavePath(savePath)
    91  	cmd.manifest.Memory(app.Name, app.Memory)
    92  	cmd.manifest.Instances(app.Name, app.InstanceCount)
    93  
    94  	if app.Command != "" {
    95  		cmd.manifest.StartCommand(app.Name, app.Command)
    96  	}
    97  
    98  	if app.BuildpackUrl != "" {
    99  		cmd.manifest.BuildpackUrl(app.Name, app.BuildpackUrl)
   100  	}
   101  
   102  	if len(app.Services) > 0 {
   103  		for _, service := range app.Services {
   104  			cmd.manifest.Service(app.Name, service.Name)
   105  		}
   106  	}
   107  
   108  	if app.HealthCheckTimeout > 0 {
   109  		cmd.manifest.HealthCheckTimeout(app.Name, app.HealthCheckTimeout)
   110  	}
   111  
   112  	if len(app.EnvironmentVars) > 0 {
   113  		sorted := sortEnvVar(app.EnvironmentVars)
   114  		for _, envVarKey := range sorted {
   115  			switch app.EnvironmentVars[envVarKey].(type) {
   116  			default:
   117  				cmd.ui.Failed(T("Failed to create manifest, unable to parse environment variable: ") + envVarKey)
   118  			case float64:
   119  				//json.Unmarshal turn all numbers to float64
   120  				value := int(app.EnvironmentVars[envVarKey].(float64))
   121  				cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%d", value))
   122  			case bool:
   123  				cmd.manifest.EnvironmentVars(app.Name, envVarKey, fmt.Sprintf("%t", app.EnvironmentVars[envVarKey].(bool)))
   124  			case string:
   125  				cmd.manifest.EnvironmentVars(app.Name, envVarKey, "\""+app.EnvironmentVars[envVarKey].(string)+"\"")
   126  			}
   127  		}
   128  	}
   129  
   130  	if len(app.Routes) > 0 {
   131  		for i := 0; i < len(app.Routes); i++ {
   132  			cmd.manifest.Domain(app.Name, app.Routes[i].Host, app.Routes[i].Domain.Name)
   133  		}
   134  	}
   135  
   136  	err := cmd.manifest.Save()
   137  	if err != nil {
   138  		cmd.ui.Failed(T("Error creating manifest file: ") + err.Error())
   139  	}
   140  
   141  	cmd.ui.Ok()
   142  	cmd.ui.Say(T("Manifest file created successfully at ") + savePath)
   143  	cmd.ui.Say("")
   144  
   145  	return nil
   146  }
   147  
   148  func sortEnvVar(vars map[string]interface{}) []string {
   149  	var varsAry []string
   150  	for k, _ := range vars {
   151  		varsAry = append(varsAry, k)
   152  	}
   153  	sort.Strings(varsAry)
   154  
   155  	return varsAry
   156  }