github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/labels_command.go (about) 1 package v7 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "code.cloudfoundry.org/cli/actor/sharedaction" 9 "code.cloudfoundry.org/cli/actor/v7action" 10 "code.cloudfoundry.org/cli/command" 11 "code.cloudfoundry.org/cli/command/flag" 12 "code.cloudfoundry.org/cli/command/translatableerror" 13 "code.cloudfoundry.org/cli/command/v7/shared" 14 "code.cloudfoundry.org/cli/types" 15 "code.cloudfoundry.org/cli/util/ui" 16 "code.cloudfoundry.org/clock" 17 ) 18 19 type ResourceType string 20 21 const ( 22 App ResourceType = "app" 23 Buildpack ResourceType = "buildpack" 24 Domain ResourceType = "domain" 25 Org ResourceType = "org" 26 Route ResourceType = "route" 27 Space ResourceType = "space" 28 Stack ResourceType = "stack" 29 ServiceBroker ResourceType = "service-broker" 30 ) 31 32 //go:generate counterfeiter . LabelsActor 33 34 type LabelsActor interface { 35 GetApplicationLabels(appName string, spaceGUID string) (map[string]types.NullString, v7action.Warnings, error) 36 GetDomainLabels(domainName string) (map[string]types.NullString, v7action.Warnings, error) 37 GetOrganizationLabels(orgName string) (map[string]types.NullString, v7action.Warnings, error) 38 GetRouteLabels(routeName string, spaceGUID string) (map[string]types.NullString, v7action.Warnings, error) 39 GetSpaceLabels(spaceName string, orgGUID string) (map[string]types.NullString, v7action.Warnings, error) 40 GetBuildpackLabels(buildpackName string, buildpackStack string) (map[string]types.NullString, v7action.Warnings, error) 41 GetStackLabels(stackName string) (map[string]types.NullString, v7action.Warnings, error) 42 } 43 44 type LabelsCommand struct { 45 RequiredArgs flag.LabelsArgs `positional-args:"yes"` 46 BuildpackStack string `long:"stack" short:"s" description:"Specify stack to disambiguate buildpacks with the same name"` 47 usage interface{} `usage:"CF_NAME labels RESOURCE RESOURCE_NAME\n\nEXAMPLES:\n cf labels app dora\n cf labels org business\n cf labels buildpack go_buildpack --stack cflinuxfs3 \n\nRESOURCES:\n app\n buildpack\n domain\n org\n route\n space\n stack"` 48 relatedCommands interface{} `related_commands:"set-label, unset-label"` 49 UI command.UI 50 Config command.Config 51 SharedActor command.SharedActor 52 Actor LabelsActor 53 } 54 55 func (cmd *LabelsCommand) Setup(config command.Config, ui command.UI) error { 56 cmd.UI = ui 57 cmd.Config = config 58 cmd.SharedActor = sharedaction.NewActor(config) 59 ccClient, _, err := shared.GetNewClientsAndConnectToCF(config, ui, "") 60 if err != nil { 61 return err 62 } 63 cmd.Actor = v7action.NewActor(ccClient, config, nil, nil, clock.NewClock()) 64 return nil 65 } 66 67 func (cmd LabelsCommand) Execute(args []string) error { 68 var ( 69 labels map[string]types.NullString 70 warnings v7action.Warnings 71 ) 72 username, err := cmd.Config.CurrentUserName() 73 if err != nil { 74 return err 75 } 76 77 err = cmd.validateFlags() 78 if err != nil { 79 return err 80 } 81 82 switch cmd.canonicalResourceTypeForName() { 83 case App: 84 labels, warnings, err = cmd.fetchAppLabels(username) 85 case Buildpack: 86 labels, warnings, err = cmd.fetchBuildpackLabels(username) 87 case Domain: 88 labels, warnings, err = cmd.fetchDomainLabels(username) 89 case Org: 90 labels, warnings, err = cmd.fetchOrgLabels(username) 91 case Route: 92 labels, warnings, err = cmd.fetchRouteLabels(username) 93 case Space: 94 labels, warnings, err = cmd.fetchSpaceLabels(username) 95 case Stack: 96 labels, warnings, err = cmd.fetchStackLabels(username) 97 default: 98 err = fmt.Errorf("Unsupported resource type of '%s'", cmd.RequiredArgs.ResourceType) 99 } 100 cmd.UI.DisplayWarnings(warnings) 101 if err != nil { 102 return err 103 } 104 105 cmd.printLabels(labels) 106 return nil 107 } 108 109 func (cmd LabelsCommand) fetchAppLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 110 err := cmd.SharedActor.CheckTarget(true, true) 111 if err != nil { 112 return nil, nil, err 113 } 114 115 cmd.UI.DisplayTextWithFlavor("Getting labels for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 116 "AppName": cmd.RequiredArgs.ResourceName, 117 "OrgName": cmd.Config.TargetedOrganization().Name, 118 "SpaceName": cmd.Config.TargetedSpace().Name, 119 "Username": username, 120 }) 121 122 cmd.UI.DisplayNewline() 123 return cmd.Actor.GetApplicationLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedSpace().GUID) 124 } 125 126 func (cmd LabelsCommand) fetchDomainLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 127 err := cmd.SharedActor.CheckTarget(false, false) 128 if err != nil { 129 return nil, nil, err 130 } 131 132 cmd.UI.DisplayTextWithFlavor("Getting labels for domain {{.DomainName}} as {{.Username}}...", map[string]interface{}{ 133 "DomainName": cmd.RequiredArgs.ResourceName, 134 "Username": username, 135 }) 136 137 cmd.UI.DisplayNewline() 138 139 return cmd.Actor.GetDomainLabels(cmd.RequiredArgs.ResourceName) 140 } 141 142 func (cmd LabelsCommand) fetchOrgLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 143 err := cmd.SharedActor.CheckTarget(false, false) 144 if err != nil { 145 return nil, nil, err 146 } 147 148 cmd.UI.DisplayTextWithFlavor("Getting labels for org {{.OrgName}} as {{.Username}}...", map[string]interface{}{ 149 "OrgName": cmd.RequiredArgs.ResourceName, 150 "Username": username, 151 }) 152 153 cmd.UI.DisplayNewline() 154 return cmd.Actor.GetOrganizationLabels(cmd.RequiredArgs.ResourceName) 155 } 156 157 func (cmd LabelsCommand) fetchRouteLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 158 err := cmd.SharedActor.CheckTarget(true, true) 159 if err != nil { 160 return nil, nil, err 161 } 162 163 cmd.UI.DisplayTextWithFlavor("Getting labels for route {{.RouteName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...", map[string]interface{}{ 164 "RouteName": cmd.RequiredArgs.ResourceName, 165 "OrgName": cmd.Config.TargetedOrganization().Name, 166 "SpaceName": cmd.Config.TargetedSpace().Name, 167 "Username": username, 168 }) 169 170 cmd.UI.DisplayNewline() 171 172 return cmd.Actor.GetRouteLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedSpace().GUID) 173 } 174 175 func (cmd LabelsCommand) fetchSpaceLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 176 err := cmd.SharedActor.CheckTarget(true, false) 177 if err != nil { 178 return nil, nil, err 179 } 180 181 cmd.UI.DisplayTextWithFlavor("Getting labels for space {{.SpaceName}} in org {{.OrgName}} as {{.Username}}...", map[string]interface{}{ 182 "SpaceName": cmd.RequiredArgs.ResourceName, 183 "OrgName": cmd.Config.TargetedOrganization().Name, 184 "Username": username, 185 }) 186 187 cmd.UI.DisplayNewline() 188 189 return cmd.Actor.GetSpaceLabels(cmd.RequiredArgs.ResourceName, cmd.Config.TargetedOrganization().GUID) 190 } 191 192 func (cmd LabelsCommand) fetchStackLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 193 err := cmd.SharedActor.CheckTarget(false, false) 194 if err != nil { 195 return nil, nil, err 196 } 197 198 cmd.UI.DisplayTextWithFlavor("Getting labels for stack {{.StackName}} as {{.Username}}...", map[string]interface{}{ 199 "StackName": cmd.RequiredArgs.ResourceName, 200 "Username": username, 201 }) 202 203 cmd.UI.DisplayNewline() 204 205 return cmd.Actor.GetStackLabels(cmd.RequiredArgs.ResourceName) 206 } 207 208 func (cmd LabelsCommand) fetchBuildpackLabels(username string) (map[string]types.NullString, v7action.Warnings, error) { 209 err := cmd.SharedActor.CheckTarget(false, false) 210 if err != nil { 211 return nil, nil, err 212 } 213 214 var template string 215 if cmd.BuildpackStack != "" { 216 template = "Getting labels for %s {{.ResourceName}} with stack {{.StackName}} as {{.User}}..." 217 } else { 218 template = "Getting labels for %s {{.ResourceName}} as {{.User}}..." 219 } 220 preFlavoringText := fmt.Sprintf(template, cmd.RequiredArgs.ResourceType) 221 cmd.UI.DisplayTextWithFlavor( 222 preFlavoringText, 223 map[string]interface{}{ 224 "ResourceName": cmd.RequiredArgs.ResourceName, 225 "StackName": cmd.BuildpackStack, 226 "User": username, 227 }, 228 ) 229 230 cmd.UI.DisplayNewline() 231 232 return cmd.Actor.GetBuildpackLabels(cmd.RequiredArgs.ResourceName, cmd.BuildpackStack) 233 } 234 235 func (cmd LabelsCommand) canonicalResourceTypeForName() ResourceType { 236 return ResourceType(strings.ToLower(cmd.RequiredArgs.ResourceType)) 237 } 238 239 func (cmd LabelsCommand) printLabels(labels map[string]types.NullString) { 240 if len(labels) == 0 { 241 cmd.UI.DisplayText("No labels found.") 242 return 243 } 244 245 keys := make([]string, 0, len(labels)) 246 for key := range labels { 247 keys = append(keys, key) 248 } 249 sort.Strings(keys) 250 251 table := [][]string{ 252 { 253 cmd.UI.TranslateText("key"), 254 cmd.UI.TranslateText("value"), 255 }, 256 } 257 258 for _, key := range keys { 259 table = append(table, []string{key, labels[key].Value}) 260 } 261 262 cmd.UI.DisplayTableWithHeader("", table, ui.DefaultTableSpacePadding) 263 } 264 265 func (cmd LabelsCommand) validateFlags() error { 266 if cmd.BuildpackStack != "" && cmd.canonicalResourceTypeForName() != Buildpack { 267 return translatableerror.ArgumentCombinationError{ 268 Args: []string{ 269 cmd.RequiredArgs.ResourceType, "--stack, -s", 270 }, 271 } 272 } 273 return nil 274 }