github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/command/namespace_status.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/nomad/api" 8 "github.com/posener/complete" 9 ) 10 11 type NamespaceStatusCommand struct { 12 Meta 13 } 14 15 func (c *NamespaceStatusCommand) Help() string { 16 helpText := ` 17 Usage: nomad namespace status [options] <namespace> 18 19 Status is used to view the status of a particular namespace. 20 21 If ACLs are enabled, this command requires a management ACL token or a token 22 that has a capability associated with the namespace. 23 24 General Options: 25 26 ` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) 27 28 return strings.TrimSpace(helpText) 29 } 30 31 func (c *NamespaceStatusCommand) AutocompleteFlags() complete.Flags { 32 return c.Meta.AutocompleteFlags(FlagSetClient) 33 } 34 35 func (c *NamespaceStatusCommand) AutocompleteArgs() complete.Predictor { 36 return NamespacePredictor(c.Meta.Client, nil) 37 } 38 39 func (c *NamespaceStatusCommand) Synopsis() string { 40 return "Display a namespace's status" 41 } 42 43 func (c *NamespaceStatusCommand) Name() string { return "namespace status" } 44 45 func (c *NamespaceStatusCommand) Run(args []string) int { 46 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 47 flags.Usage = func() { c.Ui.Output(c.Help()) } 48 49 if err := flags.Parse(args); err != nil { 50 return 1 51 } 52 53 // Check that we got one arguments 54 args = flags.Args() 55 if l := len(args); l != 1 { 56 c.Ui.Error("This command takes one argument: <namespace>") 57 c.Ui.Error(commandErrorText(c)) 58 return 1 59 } 60 61 name := args[0] 62 63 // Get the HTTP client 64 client, err := c.Meta.Client() 65 if err != nil { 66 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 67 return 1 68 } 69 70 // Do a prefix lookup 71 ns, possible, err := getNamespace(client.Namespaces(), name) 72 if err != nil { 73 c.Ui.Error(fmt.Sprintf("Error retrieving namespaces: %s", err)) 74 return 1 75 } 76 77 if len(possible) != 0 { 78 c.Ui.Error(fmt.Sprintf("Prefix matched multiple namespaces\n\n%s", formatNamespaces(possible))) 79 return 1 80 } 81 82 c.Ui.Output(formatNamespaceBasics(ns)) 83 84 if ns.Quota != "" { 85 quotas := client.Quotas() 86 spec, _, err := quotas.Info(ns.Quota, nil) 87 if err != nil { 88 c.Ui.Error(fmt.Sprintf("Error retrieving quota spec: %s", err)) 89 return 1 90 } 91 92 // Get the quota usages 93 usages, failures := quotaUsages(spec, quotas) 94 95 // Format the limits 96 c.Ui.Output(c.Colorize().Color("\n[bold]Quota Limits[reset]")) 97 c.Ui.Output(formatQuotaLimits(spec, usages)) 98 99 // Display any failures 100 if len(failures) != 0 { 101 c.Ui.Error(c.Colorize().Color("\n[bold][red]Lookup Failures[reset]")) 102 for region, failure := range failures { 103 c.Ui.Error(fmt.Sprintf(" * Failed to retrieve quota usage for region %q: %v", region, failure)) 104 return 1 105 } 106 } 107 } 108 109 return 0 110 } 111 112 // formatNamespaceBasics formats the basic information of the namespace 113 func formatNamespaceBasics(ns *api.Namespace) string { 114 basic := []string{ 115 fmt.Sprintf("Name|%s", ns.Name), 116 fmt.Sprintf("Description|%s", ns.Description), 117 fmt.Sprintf("Quota|%s", ns.Quota), 118 } 119 120 return formatKV(basic) 121 } 122 123 func getNamespace(client *api.Namespaces, ns string) (match *api.Namespace, possible []*api.Namespace, err error) { 124 // Do a prefix lookup 125 namespaces, _, err := client.PrefixList(ns, nil) 126 if err != nil { 127 return nil, nil, err 128 } 129 130 l := len(namespaces) 131 switch { 132 case l == 0: 133 return nil, nil, fmt.Errorf("Namespace %q matched no namespaces", ns) 134 case l == 1: 135 return namespaces[0], nil, nil 136 default: 137 // search for an exact match in the returned namespaces 138 for _, namespace := range namespaces { 139 if namespace.Name == ns { 140 return namespace, nil, nil 141 } 142 } 143 // if not found, return the fuzzy matches. 144 return nil, namespaces, nil 145 } 146 }