229 lines
7.6 KiB
Go
229 lines
7.6 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package agent
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
func (s *HTTPServer) DeploymentsRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
if req.Method != http.MethodGet {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
args := structs.DeploymentListRequest{}
|
|
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
|
return nil, nil
|
|
}
|
|
|
|
var out structs.DeploymentListResponse
|
|
if err := s.agent.RPC("Deployment.List", &args, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
setMeta(resp, &out.QueryMeta)
|
|
if out.Deployments == nil {
|
|
out.Deployments = make([]*structs.Deployment, 0)
|
|
}
|
|
return out.Deployments, nil
|
|
}
|
|
|
|
func (s *HTTPServer) DeploymentSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
path := strings.TrimPrefix(req.URL.Path, "/v1/deployment/")
|
|
switch {
|
|
case strings.HasPrefix(path, "allocations/"):
|
|
deploymentID := strings.TrimPrefix(path, "allocations/")
|
|
return s.deploymentAllocations(resp, req, deploymentID)
|
|
case strings.HasPrefix(path, "fail/"):
|
|
deploymentID := strings.TrimPrefix(path, "fail/")
|
|
return s.deploymentFail(resp, req, deploymentID)
|
|
case strings.HasPrefix(path, "pause/"):
|
|
deploymentID := strings.TrimPrefix(path, "pause/")
|
|
return s.deploymentPause(resp, req, deploymentID)
|
|
case strings.HasPrefix(path, "promote/"):
|
|
deploymentID := strings.TrimPrefix(path, "promote/")
|
|
return s.deploymentPromote(resp, req, deploymentID)
|
|
case strings.HasPrefix(path, "allocation-health/"):
|
|
deploymentID := strings.TrimPrefix(path, "allocation-health/")
|
|
return s.deploymentSetAllocHealth(resp, req, deploymentID)
|
|
case strings.HasPrefix(path, "unblock/"):
|
|
deploymentID := strings.TrimPrefix(path, "unblock/")
|
|
return s.deploymentUnblock(resp, req, deploymentID)
|
|
default:
|
|
return s.deploymentQuery(resp, req, path)
|
|
}
|
|
}
|
|
|
|
// TODO test and api
|
|
func (s *HTTPServer) deploymentFail(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodPut && req.Method != http.MethodPost {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
args := structs.DeploymentFailRequest{
|
|
DeploymentID: deploymentID,
|
|
}
|
|
s.parseWriteRequest(req, &args.WriteRequest)
|
|
|
|
var out structs.DeploymentUpdateResponse
|
|
if err := s.agent.RPC("Deployment.Fail", &args, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, out.Index)
|
|
return out, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentPause(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodPut && req.Method != http.MethodPost {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
var pauseRequest structs.DeploymentPauseRequest
|
|
if err := decodeBody(req, &pauseRequest); err != nil {
|
|
return nil, CodedError(http.StatusBadRequest, err.Error())
|
|
}
|
|
if pauseRequest.DeploymentID == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "DeploymentID must be specified")
|
|
}
|
|
if pauseRequest.DeploymentID != deploymentID {
|
|
return nil, CodedError(http.StatusBadRequest, "Deployment ID does not match")
|
|
}
|
|
s.parseWriteRequest(req, &pauseRequest.WriteRequest)
|
|
|
|
var out structs.DeploymentUpdateResponse
|
|
if err := s.agent.RPC("Deployment.Pause", &pauseRequest, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, out.Index)
|
|
return out, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentPromote(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodPut && req.Method != http.MethodPost {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
var promoteRequest structs.DeploymentPromoteRequest
|
|
if err := decodeBody(req, &promoteRequest); err != nil {
|
|
return nil, CodedError(http.StatusBadRequest, err.Error())
|
|
}
|
|
if promoteRequest.DeploymentID == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "DeploymentID must be specified")
|
|
}
|
|
if promoteRequest.DeploymentID != deploymentID {
|
|
return nil, CodedError(http.StatusBadRequest, "Deployment ID does not match")
|
|
}
|
|
s.parseWriteRequest(req, &promoteRequest.WriteRequest)
|
|
|
|
var out structs.DeploymentUpdateResponse
|
|
if err := s.agent.RPC("Deployment.Promote", &promoteRequest, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, out.Index)
|
|
return out, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentUnblock(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodPut && req.Method != http.MethodPost {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
var unblockRequest structs.DeploymentUnblockRequest
|
|
if err := decodeBody(req, &unblockRequest); err != nil {
|
|
return nil, CodedError(http.StatusBadRequest, err.Error())
|
|
}
|
|
if unblockRequest.DeploymentID == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "DeploymentID must be specified")
|
|
}
|
|
if unblockRequest.DeploymentID != deploymentID {
|
|
return nil, CodedError(http.StatusBadRequest, "Deployment ID does not match")
|
|
}
|
|
s.parseWriteRequest(req, &unblockRequest.WriteRequest)
|
|
|
|
var out structs.DeploymentUpdateResponse
|
|
if err := s.agent.RPC("Deployment.Unblock", &unblockRequest, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, out.Index)
|
|
return out, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentSetAllocHealth(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodPut && req.Method != http.MethodPost {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
var healthRequest structs.DeploymentAllocHealthRequest
|
|
if err := decodeBody(req, &healthRequest); err != nil {
|
|
return nil, CodedError(http.StatusBadRequest, err.Error())
|
|
}
|
|
if healthRequest.DeploymentID == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "DeploymentID must be specified")
|
|
}
|
|
if healthRequest.DeploymentID != deploymentID {
|
|
return nil, CodedError(http.StatusBadRequest, "Deployment ID does not match")
|
|
}
|
|
s.parseWriteRequest(req, &healthRequest.WriteRequest)
|
|
|
|
var out structs.DeploymentUpdateResponse
|
|
if err := s.agent.RPC("Deployment.SetAllocHealth", &healthRequest, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, out.Index)
|
|
return out, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentAllocations(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodGet {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
args := structs.DeploymentSpecificRequest{
|
|
DeploymentID: deploymentID,
|
|
}
|
|
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
|
return nil, nil
|
|
}
|
|
|
|
var out structs.AllocListResponse
|
|
if err := s.agent.RPC("Deployment.Allocations", &args, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
setMeta(resp, &out.QueryMeta)
|
|
if out.Allocations == nil {
|
|
out.Allocations = make([]*structs.AllocListStub, 0)
|
|
}
|
|
for _, alloc := range out.Allocations {
|
|
alloc.SetEventDisplayMessages()
|
|
}
|
|
return out.Allocations, nil
|
|
}
|
|
|
|
func (s *HTTPServer) deploymentQuery(resp http.ResponseWriter, req *http.Request, deploymentID string) (interface{}, error) {
|
|
if req.Method != http.MethodGet {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
args := structs.DeploymentSpecificRequest{
|
|
DeploymentID: deploymentID,
|
|
}
|
|
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
|
return nil, nil
|
|
}
|
|
|
|
var out structs.SingleDeploymentResponse
|
|
if err := s.agent.RPC("Deployment.GetDeployment", &args, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
setMeta(resp, &out.QueryMeta)
|
|
if out.Deployment == nil {
|
|
return nil, CodedError(http.StatusNotFound, "deployment not found")
|
|
}
|
|
return out.Deployment, nil
|
|
}
|