forked from hashicorp/nomad
/
service_registration_endpoint.go
130 lines (103 loc) · 4.16 KB
/
service_registration_endpoint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package agent
import (
"net/http"
"strings"
"github.com/hernad/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
}