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