github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/commands/quota/create_quota.go (about) 1 package quota 2 3 import ( 4 "fmt" 5 6 "encoding/json" 7 8 "code.cloudfoundry.org/cli/cf" 9 "code.cloudfoundry.org/cli/cf/api/quotas" 10 "code.cloudfoundry.org/cli/cf/api/resources" 11 "code.cloudfoundry.org/cli/cf/commandregistry" 12 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 13 "code.cloudfoundry.org/cli/cf/errors" 14 "code.cloudfoundry.org/cli/cf/flags" 15 "code.cloudfoundry.org/cli/cf/formatters" 16 . "code.cloudfoundry.org/cli/cf/i18n" 17 "code.cloudfoundry.org/cli/cf/models" 18 "code.cloudfoundry.org/cli/cf/requirements" 19 "code.cloudfoundry.org/cli/cf/terminal" 20 ) 21 22 type CreateQuota struct { 23 ui terminal.UI 24 config coreconfig.Reader 25 quotaRepo quotas.QuotaRepository 26 } 27 28 func init() { 29 commandregistry.Register(&CreateQuota{}) 30 } 31 32 func (cmd *CreateQuota) MetaData() commandregistry.CommandMetadata { 33 fs := make(map[string]flags.FlagSet) 34 fs["allow-paid-service-plans"] = &flags.BoolFlag{Name: "allow-paid-service-plans", Usage: T("Can provision instances of paid service plans")} 35 fs["i"] = &flags.StringFlag{ShortName: "i", Usage: T("Maximum amount of memory an application instance can have (e.g. 1024M, 1G, 10G). -1 represents an unlimited amount.")} 36 fs["m"] = &flags.StringFlag{ShortName: "m", Usage: T("Total amount of memory (e.g. 1024M, 1G, 10G)")} 37 fs["r"] = &flags.IntFlag{ShortName: "r", Usage: T("Total number of routes")} 38 fs["s"] = &flags.IntFlag{ShortName: "s", Usage: T("Total number of service instances")} 39 fs["a"] = &flags.IntFlag{ShortName: "a", Usage: T("Total number of application instances. -1 represents an unlimited amount. (Default: unlimited)")} 40 fs["reserved-route-ports"] = &flags.StringFlag{Name: "reserved-route-ports", Usage: T("Maximum number of routes that may be created with reserved ports (Default: 0)")} 41 42 return commandregistry.CommandMetadata{ 43 Name: "create-quota", 44 Description: T("Define a new resource quota"), 45 Usage: []string{ 46 "CF_NAME create-quota ", 47 T("QUOTA"), 48 " ", 49 fmt.Sprintf("[-m %s] ", T("TOTAL_MEMORY")), 50 fmt.Sprintf("[-i %s] ", T("INSTANCE_MEMORY")), 51 fmt.Sprintf("[-r %s] ", T("ROUTES")), 52 fmt.Sprintf("[-s %s] ", T("SERVICE_INSTANCES")), 53 fmt.Sprintf("[-a %s] ", T("APP_INSTANCES")), 54 "[--allow-paid-service-plans] ", 55 fmt.Sprintf("[--reserved-route-ports %s] ", T("RESERVED_ROUTE_PORTS")), 56 }, 57 Flags: fs, 58 } 59 } 60 61 func (cmd *CreateQuota) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) { 62 if len(fc.Args()) != 1 { 63 cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + commandregistry.Commands.CommandUsage("create-quota")) 64 return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 1) 65 } 66 67 reqs := []requirements.Requirement{ 68 requirementsFactory.NewLoginRequirement(), 69 } 70 71 if fc.IsSet("a") { 72 reqs = append(reqs, requirementsFactory.NewMinAPIVersionRequirement("Option '-a'", cf.OrgAppInstanceLimitMinimumAPIVersion)) 73 } 74 75 if fc.IsSet("reserved-route-ports") { 76 reqs = append(reqs, requirementsFactory.NewMinAPIVersionRequirement("Option '--reserved-route-ports'", cf.ReservedRoutePortsMinimumAPIVersion)) 77 } 78 79 return reqs, nil 80 } 81 82 func (cmd *CreateQuota) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command { 83 cmd.ui = deps.UI 84 cmd.config = deps.Config 85 cmd.quotaRepo = deps.RepoLocator.GetQuotaRepository() 86 return cmd 87 } 88 89 func (cmd *CreateQuota) Execute(context flags.FlagContext) error { 90 name := context.Args()[0] 91 92 cmd.ui.Say(T("Creating quota {{.QuotaName}} as {{.Username}}...", map[string]interface{}{ 93 "QuotaName": terminal.EntityNameColor(name), 94 "Username": terminal.EntityNameColor(cmd.config.Username()), 95 })) 96 97 quota := models.QuotaFields{ 98 Name: name, 99 } 100 101 memoryLimit := context.String("m") 102 if memoryLimit != "" { 103 parsedMemory, err := formatters.ToMegabytes(memoryLimit) 104 if err != nil { 105 return errors.New(T("Invalid memory limit: {{.MemoryLimit}}\n{{.Err}}", map[string]interface{}{"MemoryLimit": memoryLimit, "Err": err})) 106 } 107 108 quota.MemoryLimit = parsedMemory 109 } 110 111 instanceMemoryLimit := context.String("i") 112 if instanceMemoryLimit == "-1" || instanceMemoryLimit == "" { 113 quota.InstanceMemoryLimit = -1 114 } else { 115 parsedMemory, errr := formatters.ToMegabytes(instanceMemoryLimit) 116 if errr != nil { 117 return errors.New(T("Invalid instance memory limit: {{.MemoryLimit}}\n{{.Err}}", map[string]interface{}{"MemoryLimit": instanceMemoryLimit, "Err": errr})) 118 } 119 quota.InstanceMemoryLimit = parsedMemory 120 } 121 122 if context.IsSet("r") { 123 quota.RoutesLimit = context.Int("r") 124 } 125 126 if context.IsSet("s") { 127 quota.ServicesLimit = context.Int("s") 128 } 129 130 if context.IsSet("a") { 131 quota.AppInstanceLimit = context.Int("a") 132 } else { 133 quota.AppInstanceLimit = resources.UnlimitedAppInstances 134 } 135 136 if context.IsSet("allow-paid-service-plans") { 137 quota.NonBasicServicesAllowed = true 138 } 139 140 if context.IsSet("reserved-route-ports") { 141 quota.ReservedRoutePorts = json.Number(context.String("reserved-route-ports")) 142 } 143 144 err := cmd.quotaRepo.Create(quota) 145 146 httpErr, ok := err.(errors.HTTPError) 147 if ok && httpErr.ErrorCode() == errors.QuotaDefinitionNameTaken { 148 cmd.ui.Ok() 149 cmd.ui.Warn(T("Quota Definition {{.QuotaName}} already exists", map[string]interface{}{"QuotaName": quota.Name})) 150 return nil 151 } 152 153 if err != nil { 154 return err 155 } 156 157 cmd.ui.Ok() 158 return nil 159 }