github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/job_deployments.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hashicorp/nomad/api"
     8  	"github.com/hashicorp/nomad/api/contexts"
     9  	"github.com/posener/complete"
    10  )
    11  
    12  type JobDeploymentsCommand struct {
    13  	Meta
    14  }
    15  
    16  func (c *JobDeploymentsCommand) Help() string {
    17  	helpText := `
    18  Usage: nomad job deployments [options] <job>
    19  
    20    Deployments is used to display the deployments for a particular job.
    21  
    22    When ACLs are enabled, this command requires a token with the 'read-job' and
    23    'list-jobs' capabilities for the job's namespace.
    24  
    25  General Options:
    26  
    27    ` + generalOptionsUsage(usageOptsDefault) + `
    28  
    29  Deployments Options:
    30  
    31    -json
    32      Output the deployments in a JSON format.
    33  
    34    -t
    35      Format and display deployments using a Go template.
    36  
    37    -latest
    38      Display the latest deployment only.
    39  
    40    -verbose
    41      Display full information.
    42  
    43    -all
    44      Display all deployments matching the job ID, including those
    45      from an older instance of the job.
    46  `
    47  	return strings.TrimSpace(helpText)
    48  }
    49  
    50  func (c *JobDeploymentsCommand) Synopsis() string {
    51  	return "List deployments for a job"
    52  }
    53  
    54  func (c *JobDeploymentsCommand) AutocompleteFlags() complete.Flags {
    55  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    56  		complete.Flags{
    57  			"-json":    complete.PredictNothing,
    58  			"-t":       complete.PredictAnything,
    59  			"-latest":  complete.PredictNothing,
    60  			"-verbose": complete.PredictNothing,
    61  			"-all":     complete.PredictNothing,
    62  		})
    63  }
    64  
    65  func (c *JobDeploymentsCommand) AutocompleteArgs() complete.Predictor {
    66  	return complete.PredictFunc(func(a complete.Args) []string {
    67  		client, err := c.Meta.Client()
    68  		if err != nil {
    69  			return nil
    70  		}
    71  
    72  		resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil)
    73  		if err != nil {
    74  			return []string{}
    75  		}
    76  		return resp.Matches[contexts.Jobs]
    77  	})
    78  }
    79  
    80  func (c *JobDeploymentsCommand) Name() string { return "job deployments" }
    81  
    82  func (c *JobDeploymentsCommand) Run(args []string) int {
    83  	var json, latest, verbose, all bool
    84  	var tmpl string
    85  
    86  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    87  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    88  	flags.BoolVar(&latest, "latest", false, "")
    89  	flags.BoolVar(&verbose, "verbose", false, "")
    90  	flags.BoolVar(&all, "all", false, "")
    91  	flags.BoolVar(&json, "json", false, "")
    92  	flags.StringVar(&tmpl, "t", "", "")
    93  
    94  	if err := flags.Parse(args); err != nil {
    95  		return 1
    96  	}
    97  
    98  	// Check that we got exactly one node
    99  	args = flags.Args()
   100  	if l := len(args); l != 1 {
   101  		c.Ui.Error("This command takes one argument: <job>")
   102  		c.Ui.Error(commandErrorText(c))
   103  		return 1
   104  	}
   105  
   106  	// Get the HTTP client
   107  	client, err := c.Meta.Client()
   108  	if err != nil {
   109  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
   110  		return 1
   111  	}
   112  
   113  	jobID := strings.TrimSpace(args[0])
   114  
   115  	// Check if the job exists
   116  	jobs, _, err := client.Jobs().PrefixList(jobID)
   117  	if err != nil {
   118  		c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err))
   119  		return 1
   120  	}
   121  	if len(jobs) == 0 {
   122  		c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
   123  		return 1
   124  	}
   125  	if len(jobs) > 1 {
   126  		if (jobID != jobs[0].ID) || (c.allNamespaces() && jobs[0].ID == jobs[1].ID) {
   127  			c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs, c.allNamespaces())))
   128  			return 1
   129  		}
   130  	}
   131  
   132  	jobID = jobs[0].ID
   133  	q := &api.QueryOptions{Namespace: jobs[0].JobSummary.Namespace}
   134  
   135  	// Truncate the id unless full length is requested
   136  	length := shortId
   137  	if verbose {
   138  		length = fullId
   139  	}
   140  
   141  	if latest {
   142  		deploy, _, err := client.Jobs().LatestDeployment(jobID, q)
   143  		if err != nil {
   144  			c.Ui.Error(fmt.Sprintf("Error retrieving deployments: %s", err))
   145  			return 1
   146  		}
   147  
   148  		if json || len(tmpl) > 0 {
   149  			out, err := Format(json, tmpl, deploy)
   150  			if err != nil {
   151  				c.Ui.Error(err.Error())
   152  				return 1
   153  			}
   154  
   155  			c.Ui.Output(out)
   156  			return 0
   157  		}
   158  
   159  		c.Ui.Output(c.Colorize().Color(formatDeployment(client, deploy, length)))
   160  		return 0
   161  	}
   162  
   163  	deploys, _, err := client.Jobs().Deployments(jobID, all, q)
   164  	if err != nil {
   165  		c.Ui.Error(fmt.Sprintf("Error retrieving deployments: %s", err))
   166  		return 1
   167  	}
   168  
   169  	if json || len(tmpl) > 0 {
   170  		out, err := Format(json, tmpl, deploys)
   171  		if err != nil {
   172  			c.Ui.Error(err.Error())
   173  			return 1
   174  		}
   175  
   176  		c.Ui.Output(out)
   177  		return 0
   178  	}
   179  
   180  	c.Ui.Output(formatDeployments(deploys, length))
   181  	return 0
   182  }