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  }