131 lines
4.2 KiB
Go
131 lines
4.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package agent
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
// ServiceRegistrationListRequest performs a listing of service registrations
|
|
// using the structs.ServiceRegistrationListRPCMethod RPC endpoint and is
|
|
// callable via the /v1/services HTTP API.
|
|
func (s *HTTPServer) ServiceRegistrationListRequest(
|
|
resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
|
|
// The endpoint only supports GET requests.
|
|
if req.Method != http.MethodGet {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
// Set up the request args and parse this to ensure the query options are
|
|
// set.
|
|
args := structs.ServiceRegistrationListRequest{}
|
|
|
|
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
|
return nil, nil
|
|
}
|
|
|
|
// Perform the RPC request.
|
|
var reply structs.ServiceRegistrationListResponse
|
|
if err := s.agent.RPC(structs.ServiceRegistrationListRPCMethod, &args, &reply); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
setMeta(resp, &reply.QueryMeta)
|
|
|
|
if reply.Services == nil {
|
|
reply.Services = make([]*structs.ServiceRegistrationListStub, 0)
|
|
}
|
|
return reply.Services, nil
|
|
}
|
|
|
|
// ServiceRegistrationRequest is callable via the /v1/service/ HTTP API and
|
|
// handles service reads and individual service registration deletions.
|
|
func (s *HTTPServer) ServiceRegistrationRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
|
|
|
|
// Grab the suffix of the request, so we can further understand it.
|
|
reqSuffix := strings.TrimPrefix(req.URL.Path, "/v1/service/")
|
|
|
|
// Split the request suffix in order to identify whether this is a lookup
|
|
// of a service, or whether this includes a service and service identifier.
|
|
suffixParts := strings.Split(reqSuffix, "/")
|
|
|
|
switch len(suffixParts) {
|
|
case 1:
|
|
// This endpoint only supports GET.
|
|
if req.Method != http.MethodGet {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
// Ensure the service ID is not an empty string which is possible if
|
|
// the caller requested "/v1/service/service-name/"
|
|
if suffixParts[0] == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "missing service name")
|
|
}
|
|
|
|
return s.serviceGetRequest(resp, req, suffixParts[0])
|
|
|
|
case 2:
|
|
// This endpoint only supports DELETE.
|
|
if req.Method != http.MethodDelete {
|
|
return nil, CodedError(http.StatusMethodNotAllowed, ErrInvalidMethod)
|
|
}
|
|
|
|
// Ensure the service ID is not an empty string which is possible if
|
|
// the caller requested "/v1/service/service-name/"
|
|
if suffixParts[1] == "" {
|
|
return nil, CodedError(http.StatusBadRequest, "missing service id")
|
|
}
|
|
|
|
return s.serviceDeleteRequest(resp, req, suffixParts[1])
|
|
|
|
default:
|
|
return nil, CodedError(http.StatusBadRequest, "invalid URI")
|
|
}
|
|
}
|
|
|
|
// serviceGetRequest performs a reading of service registrations by name using
|
|
// the structs.ServiceRegistrationGetServiceRPCMethod RPC endpoint.
|
|
func (s *HTTPServer) serviceGetRequest(
|
|
resp http.ResponseWriter, req *http.Request, serviceName string) (interface{}, error) {
|
|
|
|
args := structs.ServiceRegistrationByNameRequest{
|
|
ServiceName: serviceName,
|
|
Choose: req.URL.Query().Get("choose"),
|
|
}
|
|
if s.parse(resp, req, &args.Region, &args.QueryOptions) {
|
|
return nil, nil
|
|
}
|
|
|
|
var reply structs.ServiceRegistrationByNameResponse
|
|
if err := s.agent.RPC(structs.ServiceRegistrationGetServiceRPCMethod, &args, &reply); err != nil {
|
|
return nil, err
|
|
}
|
|
setMeta(resp, &reply.QueryMeta)
|
|
|
|
if reply.Services == nil {
|
|
reply.Services = make([]*structs.ServiceRegistration, 0)
|
|
}
|
|
return reply.Services, nil
|
|
}
|
|
|
|
// serviceDeleteRequest performs a reading of service registrations by name using
|
|
// the structs.ServiceRegistrationDeleteByIDRPCMethod RPC endpoint.
|
|
func (s *HTTPServer) serviceDeleteRequest(
|
|
resp http.ResponseWriter, req *http.Request, serviceID string) (interface{}, error) {
|
|
|
|
args := structs.ServiceRegistrationDeleteByIDRequest{ID: serviceID}
|
|
s.parseWriteRequest(req, &args.WriteRequest)
|
|
|
|
var reply structs.ServiceRegistrationDeleteByIDResponse
|
|
if err := s.agent.RPC(structs.ServiceRegistrationDeleteByIDRPCMethod, &args, &reply); err != nil {
|
|
return nil, err
|
|
}
|
|
setIndex(resp, reply.Index)
|
|
return nil, nil
|
|
}
|