github.com/hernad/nomad@v1.6.112/command/scaling_policy_list.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package command 5 6 import ( 7 "fmt" 8 "sort" 9 "strings" 10 11 "github.com/hernad/nomad/api" 12 "github.com/mitchellh/cli" 13 "github.com/posener/complete" 14 ) 15 16 // Ensure ScalingPolicyListCommand satisfies the cli.Command interface. 17 var _ cli.Command = &ScalingPolicyListCommand{} 18 19 // ScalingPolicyListCommand implements cli.Command. 20 type ScalingPolicyListCommand struct { 21 Meta 22 } 23 24 // Help satisfies the cli.Command Help function. 25 func (s *ScalingPolicyListCommand) Help() string { 26 helpText := ` 27 Usage: nomad scaling policy list [options] 28 29 List is used to list the currently configured scaling policies. 30 31 If ACLs are enabled, this command requires a token with the 'read-job' and 32 'list-jobs' capabilities for the namespace of all policies. Any namespaces 33 that the token does not have access to will have its policies filtered from 34 the results. 35 36 General Options: 37 38 ` + generalOptionsUsage(usageOptsDefault) + ` 39 40 Policy Info Options: 41 42 -job 43 Specifies the job ID to filter the scaling policies list by. 44 45 -type 46 Filter scaling policies by type. 47 48 -verbose 49 Display full information. 50 51 -json 52 Output the scaling policy in its JSON format. 53 54 -t 55 Format and display the scaling policy using a Go template. 56 ` 57 return strings.TrimSpace(helpText) 58 } 59 60 // Synopsis satisfies the cli.Command Synopsis function. 61 func (s *ScalingPolicyListCommand) Synopsis() string { 62 return "Display all Nomad scaling policies" 63 } 64 65 func (s *ScalingPolicyListCommand) AutocompleteFlags() complete.Flags { 66 return mergeAutocompleteFlags(s.Meta.AutocompleteFlags(FlagSetClient), 67 complete.Flags{ 68 "-verbose": complete.PredictNothing, 69 "-job": complete.PredictNothing, 70 "-type": complete.PredictNothing, 71 "-json": complete.PredictNothing, 72 "-t": complete.PredictAnything, 73 }) 74 } 75 76 // Name returns the name of this command. 77 func (s *ScalingPolicyListCommand) Name() string { return "scaling policy list" } 78 79 // Run satisfies the cli.Command Run function. 80 func (s *ScalingPolicyListCommand) Run(args []string) int { 81 var json, verbose bool 82 var tmpl, policyType, job string 83 84 flags := s.Meta.FlagSet(s.Name(), FlagSetClient) 85 flags.Usage = func() { s.Ui.Output(s.Help()) } 86 flags.BoolVar(&verbose, "verbose", false, "") 87 flags.BoolVar(&json, "json", false, "") 88 flags.StringVar(&tmpl, "t", "", "") 89 flags.StringVar(&policyType, "type", "", "") 90 flags.StringVar(&job, "job", "", "") 91 if err := flags.Parse(args); err != nil { 92 return 1 93 } 94 95 if args = flags.Args(); len(args) > 0 { 96 s.Ui.Error("This command takes no arguments") 97 s.Ui.Error(commandErrorText(s)) 98 return 1 99 } 100 101 // Truncate the id unless full length is requested 102 length := shortId 103 if verbose { 104 length = fullId 105 } 106 107 // Get the HTTP client. 108 client, err := s.Meta.Client() 109 if err != nil { 110 s.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 111 return 1 112 } 113 114 q := &api.QueryOptions{ 115 Params: map[string]string{}, 116 } 117 if policyType != "" { 118 q.Params["type"] = policyType 119 } 120 if job != "" { 121 q.Params["job"] = job 122 } 123 policies, _, err := client.Scaling().ListPolicies(q) 124 if err != nil { 125 s.Ui.Error(fmt.Sprintf("Error listing scaling policies: %s", err)) 126 return 1 127 } 128 129 if json || len(tmpl) > 0 { 130 out, err := Format(json, tmpl, policies) 131 if err != nil { 132 s.Ui.Error(err.Error()) 133 return 1 134 } 135 s.Ui.Output(out) 136 return 0 137 } 138 139 output := formatScalingPolicies(policies, length) 140 s.Ui.Output(output) 141 return 0 142 } 143 144 func formatScalingPolicies(stubs []*api.ScalingPolicyListStub, uuidLength int) string { 145 if len(stubs) == 0 { 146 return "No policies found" 147 } 148 149 // Create the output table header. 150 policies := []string{"ID|Enabled|Type|Target"} 151 152 // Sort the list of policies based on their target. 153 sortedPolicies := scalingPolicyStubList{policies: stubs} 154 sort.Sort(sortedPolicies) 155 156 // Iterate the policies and add to the output. 157 for _, policy := range sortedPolicies.policies { 158 policies = append(policies, fmt.Sprintf( 159 "%s|%v|%s|%s", 160 limit(policy.ID, uuidLength), 161 policy.Enabled, 162 policy.Type, 163 formatScalingPolicyTarget(policy.Target))) 164 } 165 return formatList(policies) 166 } 167 168 // scalingPolicyStubList is a wrapper around []*api.ScalingPolicyListStub that 169 // list us sort the policies alphabetically based on their target. 170 type scalingPolicyStubList struct { 171 policies []*api.ScalingPolicyListStub 172 } 173 174 // Len satisfies the Len function of the sort.Interface interface. 175 func (s scalingPolicyStubList) Len() int { return len(s.policies) } 176 177 // Swap satisfies the Swap function of the sort.Interface interface. 178 func (s scalingPolicyStubList) Swap(i, j int) { 179 s.policies[i], s.policies[j] = s.policies[j], s.policies[i] 180 } 181 182 // Less satisfies the Less function of the sort.Interface interface. 183 func (s scalingPolicyStubList) Less(i, j int) bool { 184 185 iTarget := formatScalingPolicyTarget(s.policies[i].Target) 186 jTarget := formatScalingPolicyTarget(s.policies[j].Target) 187 188 stringList := []string{iTarget, jTarget} 189 sort.Strings(stringList) 190 191 return stringList[0] == iTarget 192 }