github.com/hashicorp/nomad/api@v0.0.0-20240306165712-3193ac204f65/deployments.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package api
     5  
     6  import (
     7  	"sort"
     8  	"time"
     9  )
    10  
    11  // Deployments is used to query the deployments endpoints.
    12  type Deployments struct {
    13  	client *Client
    14  }
    15  
    16  // Deployments returns a new handle on the deployments.
    17  func (c *Client) Deployments() *Deployments {
    18  	return &Deployments{client: c}
    19  }
    20  
    21  // List is used to dump all the deployments.
    22  func (d *Deployments) List(q *QueryOptions) ([]*Deployment, *QueryMeta, error) {
    23  	var resp []*Deployment
    24  	qm, err := d.client.query("/v1/deployments", &resp, q)
    25  	if err != nil {
    26  		return nil, nil, err
    27  	}
    28  	sort.Sort(DeploymentIndexSort(resp))
    29  	return resp, qm, nil
    30  }
    31  
    32  func (d *Deployments) PrefixList(prefix string) ([]*Deployment, *QueryMeta, error) {
    33  	return d.List(&QueryOptions{Prefix: prefix})
    34  }
    35  
    36  // Info is used to query a single deployment by its ID.
    37  func (d *Deployments) Info(deploymentID string, q *QueryOptions) (*Deployment, *QueryMeta, error) {
    38  	var resp Deployment
    39  	qm, err := d.client.query("/v1/deployment/"+deploymentID, &resp, q)
    40  	if err != nil {
    41  		return nil, nil, err
    42  	}
    43  	return &resp, qm, nil
    44  }
    45  
    46  // Allocations is used to retrieve a set of allocations that are part of the
    47  // deployment
    48  func (d *Deployments) Allocations(deploymentID string, q *QueryOptions) ([]*AllocationListStub, *QueryMeta, error) {
    49  	var resp []*AllocationListStub
    50  	qm, err := d.client.query("/v1/deployment/allocations/"+deploymentID, &resp, q)
    51  	if err != nil {
    52  		return nil, nil, err
    53  	}
    54  	sort.Sort(AllocIndexSort(resp))
    55  	return resp, qm, nil
    56  }
    57  
    58  // Fail is used to fail the given deployment.
    59  func (d *Deployments) Fail(deploymentID string, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
    60  	var resp DeploymentUpdateResponse
    61  	req := &DeploymentFailRequest{
    62  		DeploymentID: deploymentID,
    63  	}
    64  	wm, err := d.client.put("/v1/deployment/fail/"+deploymentID, req, &resp, q)
    65  	if err != nil {
    66  		return nil, nil, err
    67  	}
    68  	return &resp, wm, nil
    69  }
    70  
    71  // Pause is used to pause or unpause the given deployment.
    72  func (d *Deployments) Pause(deploymentID string, pause bool, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
    73  	var resp DeploymentUpdateResponse
    74  	req := &DeploymentPauseRequest{
    75  		DeploymentID: deploymentID,
    76  		Pause:        pause,
    77  	}
    78  	wm, err := d.client.put("/v1/deployment/pause/"+deploymentID, req, &resp, q)
    79  	if err != nil {
    80  		return nil, nil, err
    81  	}
    82  	return &resp, wm, nil
    83  }
    84  
    85  // PromoteAll is used to promote all canaries in the given deployment
    86  func (d *Deployments) PromoteAll(deploymentID string, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
    87  	var resp DeploymentUpdateResponse
    88  	req := &DeploymentPromoteRequest{
    89  		DeploymentID: deploymentID,
    90  		All:          true,
    91  	}
    92  	wm, err := d.client.put("/v1/deployment/promote/"+deploymentID, req, &resp, q)
    93  	if err != nil {
    94  		return nil, nil, err
    95  	}
    96  	return &resp, wm, nil
    97  }
    98  
    99  // PromoteGroups is used to promote canaries in the passed groups in the given deployment
   100  func (d *Deployments) PromoteGroups(deploymentID string, groups []string, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
   101  	var resp DeploymentUpdateResponse
   102  	req := &DeploymentPromoteRequest{
   103  		DeploymentID: deploymentID,
   104  		Groups:       groups,
   105  	}
   106  	wm, err := d.client.put("/v1/deployment/promote/"+deploymentID, req, &resp, q)
   107  	if err != nil {
   108  		return nil, nil, err
   109  	}
   110  	return &resp, wm, nil
   111  }
   112  
   113  // Unblock is used to unblock the given deployment.
   114  func (d *Deployments) Unblock(deploymentID string, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
   115  	var resp DeploymentUpdateResponse
   116  	req := &DeploymentUnblockRequest{
   117  		DeploymentID: deploymentID,
   118  	}
   119  	wm, err := d.client.put("/v1/deployment/unblock/"+deploymentID, req, &resp, q)
   120  	if err != nil {
   121  		return nil, nil, err
   122  	}
   123  	return &resp, wm, nil
   124  }
   125  
   126  // SetAllocHealth is used to set allocation health for allocs that are part of
   127  // the given deployment
   128  func (d *Deployments) SetAllocHealth(deploymentID string, healthy, unhealthy []string, q *WriteOptions) (*DeploymentUpdateResponse, *WriteMeta, error) {
   129  	var resp DeploymentUpdateResponse
   130  	req := &DeploymentAllocHealthRequest{
   131  		DeploymentID:           deploymentID,
   132  		HealthyAllocationIDs:   healthy,
   133  		UnhealthyAllocationIDs: unhealthy,
   134  	}
   135  	wm, err := d.client.put("/v1/deployment/allocation-health/"+deploymentID, req, &resp, q)
   136  	if err != nil {
   137  		return nil, nil, err
   138  	}
   139  	return &resp, wm, nil
   140  }
   141  
   142  const (
   143  	DeploymentStatusRunning    = "running"
   144  	DeploymentStatusPaused     = "paused"
   145  	DeploymentStatusFailed     = "failed"
   146  	DeploymentStatusSuccessful = "successful"
   147  	DeploymentStatusCancelled  = "cancelled"
   148  	DeploymentStatusPending    = "pending"
   149  	DeploymentStatusBlocked    = "blocked"
   150  	DeploymentStatusUnblocking = "unblocking"
   151  )
   152  
   153  // Deployment is used to serialize an deployment.
   154  type Deployment struct {
   155  	// ID is a generated UUID for the deployment
   156  	ID string
   157  
   158  	// Namespace is the namespace the deployment is created in
   159  	Namespace string
   160  
   161  	// JobID is the job the deployment is created for
   162  	JobID string
   163  
   164  	// JobVersion is the version of the job at which the deployment is tracking
   165  	JobVersion uint64
   166  
   167  	// JobModifyIndex is the ModifyIndex of the job which the deployment is
   168  	// tracking.
   169  	JobModifyIndex uint64
   170  
   171  	// JobSpecModifyIndex is the JobModifyIndex of the job which the
   172  	// deployment is tracking.
   173  	JobSpecModifyIndex uint64
   174  
   175  	// JobCreateIndex is the create index of the job which the deployment is
   176  	// tracking. It is needed so that if the job gets stopped and reran we can
   177  	// present the correct list of deployments for the job and not old ones.
   178  	JobCreateIndex uint64
   179  
   180  	// IsMultiregion specifies if this deployment is part of a multi-region deployment
   181  	IsMultiregion bool
   182  
   183  	// TaskGroups is the set of task groups effected by the deployment and their
   184  	// current deployment status.
   185  	TaskGroups map[string]*DeploymentState
   186  
   187  	// The status of the deployment
   188  	Status string
   189  
   190  	// StatusDescription allows a human readable description of the deployment
   191  	// status.
   192  	StatusDescription string
   193  
   194  	CreateIndex uint64
   195  	ModifyIndex uint64
   196  }
   197  
   198  // DeploymentState tracks the state of a deployment for a given task group.
   199  type DeploymentState struct {
   200  	PlacedCanaries    []string
   201  	AutoRevert        bool
   202  	ProgressDeadline  time.Duration
   203  	RequireProgressBy time.Time
   204  	Promoted          bool
   205  	DesiredCanaries   int
   206  	DesiredTotal      int
   207  	PlacedAllocs      int
   208  	HealthyAllocs     int
   209  	UnhealthyAllocs   int
   210  }
   211  
   212  // DeploymentIndexSort is a wrapper to sort deployments by CreateIndex. We
   213  // reverse the test so that we get the highest index first.
   214  type DeploymentIndexSort []*Deployment
   215  
   216  func (d DeploymentIndexSort) Len() int {
   217  	return len(d)
   218  }
   219  
   220  func (d DeploymentIndexSort) Less(i, j int) bool {
   221  	return d[i].CreateIndex > d[j].CreateIndex
   222  }
   223  
   224  func (d DeploymentIndexSort) Swap(i, j int) {
   225  	d[i], d[j] = d[j], d[i]
   226  }
   227  
   228  // DeploymentUpdateResponse is used to respond to a deployment change. The
   229  // response will include the modify index of the deployment as well as details
   230  // of any triggered evaluation.
   231  type DeploymentUpdateResponse struct {
   232  	EvalID                string
   233  	EvalCreateIndex       uint64
   234  	DeploymentModifyIndex uint64
   235  	RevertedJobVersion    *uint64
   236  	WriteMeta
   237  }
   238  
   239  // DeploymentAllocHealthRequest is used to set the health of a set of
   240  // allocations as part of a deployment.
   241  type DeploymentAllocHealthRequest struct {
   242  	DeploymentID string
   243  
   244  	// Marks these allocations as healthy, allow further allocations
   245  	// to be rolled.
   246  	HealthyAllocationIDs []string
   247  
   248  	// Any unhealthy allocations fail the deployment
   249  	UnhealthyAllocationIDs []string
   250  
   251  	WriteRequest
   252  }
   253  
   254  // DeploymentPromoteRequest is used to promote task groups in a deployment
   255  type DeploymentPromoteRequest struct {
   256  	DeploymentID string
   257  
   258  	// All is to promote all task groups
   259  	All bool
   260  
   261  	// Groups is used to set the promotion status per task group
   262  	Groups []string
   263  
   264  	WriteRequest
   265  }
   266  
   267  // DeploymentPauseRequest is used to pause a deployment
   268  type DeploymentPauseRequest struct {
   269  	DeploymentID string
   270  
   271  	// Pause sets the pause status
   272  	Pause bool
   273  
   274  	WriteRequest
   275  }
   276  
   277  // DeploymentSpecificRequest is used to make a request specific to a particular
   278  // deployment
   279  type DeploymentSpecificRequest struct {
   280  	DeploymentID string
   281  	QueryOptions
   282  }
   283  
   284  // DeploymentFailRequest is used to fail a particular deployment
   285  type DeploymentFailRequest struct {
   286  	DeploymentID string
   287  	WriteRequest
   288  }
   289  
   290  // DeploymentUnblockRequest is used to unblock a particular deployment
   291  type DeploymentUnblockRequest struct {
   292  	DeploymentID string
   293  	WriteRequest
   294  }
   295  
   296  // SingleDeploymentResponse is used to respond with a single deployment
   297  type SingleDeploymentResponse struct {
   298  	Deployment *Deployment
   299  	QueryMeta
   300  }