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