github.com/hernad/nomad@v1.6.112/nomad/structs/service_registration.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package structs 5 6 import ( 7 "crypto/md5" 8 "encoding/binary" 9 "fmt" 10 11 "github.com/hernad/nomad/helper" 12 "github.com/hernad/nomad/helper/ipaddr" 13 "golang.org/x/exp/slices" 14 ) 15 16 const ( 17 // ServiceRegistrationUpsertRPCMethod is the RPC method for upserting 18 // service registrations into Nomad state. 19 // 20 // Args: ServiceRegistrationUpsertRequest 21 // Reply: ServiceRegistrationUpsertResponse 22 ServiceRegistrationUpsertRPCMethod = "ServiceRegistration.Upsert" 23 24 // ServiceRegistrationDeleteByIDRPCMethod is the RPC method for deleting 25 // a service registration by its ID. 26 // 27 // Args: ServiceRegistrationDeleteByIDRequest 28 // Reply: ServiceRegistrationDeleteByIDResponse 29 ServiceRegistrationDeleteByIDRPCMethod = "ServiceRegistration.DeleteByID" 30 31 // ServiceRegistrationListRPCMethod is the RPC method for listing service 32 // registrations within Nomad. 33 // 34 // Args: ServiceRegistrationListRequest 35 // Reply: ServiceRegistrationListResponse 36 ServiceRegistrationListRPCMethod = "ServiceRegistration.List" 37 38 // ServiceRegistrationGetServiceRPCMethod is the RPC method for detailing a 39 // service and its registrations according to its name. 40 // 41 // Args: ServiceRegistrationByNameRequest 42 // Reply: ServiceRegistrationByNameResponse 43 ServiceRegistrationGetServiceRPCMethod = "ServiceRegistration.GetService" 44 ) 45 46 // ServiceRegistration is the internal representation of a Nomad service 47 // registration. 48 type ServiceRegistration struct { 49 50 // ID is the unique identifier for this registration. It currently follows 51 // the Consul service registration format to provide consistency between 52 // the two solutions. 53 ID string 54 55 // ServiceName is the human friendly identifier for this service 56 // registration. This is not unique. 57 ServiceName string 58 59 // Namespace is Job.Namespace and therefore the namespace in which this 60 // service registration resides. 61 Namespace string 62 63 // NodeID is Node.ID on which this service registration is currently 64 // running. 65 NodeID string 66 67 // Datacenter is the DC identifier of the node as identified by 68 // Node.Datacenter. It is denormalized here to allow filtering services by 69 // datacenter without looking up every node. 70 Datacenter string 71 72 // JobID is Job.ID and represents the job which contained the service block 73 // which resulted in this service registration. 74 JobID string 75 76 // AllocID is Allocation.ID and represents the allocation within which this 77 // service is running. 78 AllocID string 79 80 // Tags are determined from either Service.Tags or Service.CanaryTags and 81 // help identify this service. Tags can also be used to perform lookups of 82 // services depending on their state and role. 83 Tags []string 84 85 // Address is the IP address of this service registration. This information 86 // comes from the client and is not guaranteed to be routable; this depends 87 // on cluster network topology. 88 Address string 89 90 // Port is the port number on which this service registration is bound. It 91 // is determined by a combination of factors on the client. 92 Port int 93 94 CreateIndex uint64 95 ModifyIndex uint64 96 } 97 98 // Copy creates a deep copy of the service registration. This copy can then be 99 // safely modified. It handles nil objects. 100 func (s *ServiceRegistration) Copy() *ServiceRegistration { 101 if s == nil { 102 return nil 103 } 104 105 ns := new(ServiceRegistration) 106 *ns = *s 107 ns.Tags = slices.Clone(ns.Tags) 108 109 return ns 110 } 111 112 // Equal performs an equality check on the two service registrations. It 113 // handles nil objects. 114 func (s *ServiceRegistration) Equal(o *ServiceRegistration) bool { 115 if s == nil || o == nil { 116 return s == o 117 } 118 if s.ID != o.ID { 119 return false 120 } 121 if s.ServiceName != o.ServiceName { 122 return false 123 } 124 if s.NodeID != o.NodeID { 125 return false 126 } 127 if s.Datacenter != o.Datacenter { 128 return false 129 } 130 if s.JobID != o.JobID { 131 return false 132 } 133 if s.AllocID != o.AllocID { 134 return false 135 } 136 if s.Namespace != o.Namespace { 137 return false 138 } 139 if s.Address != o.Address { 140 return false 141 } 142 if s.Port != o.Port { 143 return false 144 } 145 if !helper.SliceSetEq(s.Tags, o.Tags) { 146 return false 147 } 148 return true 149 } 150 151 // Validate ensures the upserted service registration contains valid 152 // information and routing capabilities. Objects should never fail here as 153 // Nomad controls the entire registration process; but it's possible 154 // configuration problems could cause failures. 155 func (s *ServiceRegistration) Validate() error { 156 if ipaddr.IsAny(s.Address) { 157 return fmt.Errorf("invalid service registration address") 158 } 159 return nil 160 } 161 162 // GetID is a helper for getting the ID when the object may be nil and is 163 // required for pagination. 164 func (s *ServiceRegistration) GetID() string { 165 if s == nil { 166 return "" 167 } 168 return s.ID 169 } 170 171 // GetNamespace is a helper for getting the namespace when the object may be 172 // nil and is required for pagination. 173 func (s *ServiceRegistration) GetNamespace() string { 174 if s == nil { 175 return "" 176 } 177 return s.Namespace 178 } 179 180 // HashWith generates a unique value representative of s based on the contents of s. 181 func (s *ServiceRegistration) HashWith(key string) string { 182 buf := make([]byte, 8) 183 binary.BigEndian.PutUint64(buf, uint64(s.Port)) 184 185 sum := md5.New() 186 sum.Write(buf) 187 sum.Write([]byte(s.AllocID)) 188 sum.Write([]byte(s.ID)) 189 sum.Write([]byte(s.Namespace)) 190 sum.Write([]byte(s.Address)) 191 sum.Write([]byte(s.ServiceName)) 192 for _, tag := range s.Tags { 193 sum.Write([]byte(tag)) 194 } 195 sum.Write([]byte(key)) 196 return fmt.Sprintf("%x", sum.Sum(nil)) 197 } 198 199 // ServiceRegistrationUpsertRequest is the request object used to upsert one or 200 // more service registrations. 201 type ServiceRegistrationUpsertRequest struct { 202 Services []*ServiceRegistration 203 WriteRequest 204 } 205 206 // ServiceRegistrationUpsertResponse is the response object when one or more 207 // service registrations have been successfully upserted into state. 208 type ServiceRegistrationUpsertResponse struct { 209 WriteMeta 210 } 211 212 // ServiceRegistrationDeleteByIDRequest is the request object to delete a 213 // service registration as specified by the ID parameter. 214 type ServiceRegistrationDeleteByIDRequest struct { 215 ID string 216 WriteRequest 217 } 218 219 // ServiceRegistrationDeleteByIDResponse is the response object when performing a 220 // deletion of an individual service registration. 221 type ServiceRegistrationDeleteByIDResponse struct { 222 WriteMeta 223 } 224 225 // ServiceRegistrationDeleteByNodeIDRequest is the request object to delete all 226 // service registrations assigned to a particular node. 227 type ServiceRegistrationDeleteByNodeIDRequest struct { 228 NodeID string 229 WriteRequest 230 } 231 232 // ServiceRegistrationDeleteByNodeIDResponse is the response object when 233 // performing a deletion of all service registrations assigned to a particular 234 // node. 235 type ServiceRegistrationDeleteByNodeIDResponse struct { 236 WriteMeta 237 } 238 239 // ServiceRegistrationListRequest is the request object when performing service 240 // registration listings. 241 type ServiceRegistrationListRequest struct { 242 QueryOptions 243 } 244 245 // ServiceRegistrationListResponse is the response object when performing a 246 // list of services. This is specifically concise to reduce the serialisation 247 // and network costs endpoint incur, particularly when performing blocking list 248 // queries. 249 type ServiceRegistrationListResponse struct { 250 Services []*ServiceRegistrationListStub 251 QueryMeta 252 } 253 254 // ServiceRegistrationListStub is the object which contains a list of namespace 255 // service registrations and their tags. 256 type ServiceRegistrationListStub struct { 257 Namespace string 258 Services []*ServiceRegistrationStub 259 } 260 261 // ServiceRegistrationStub is the stub object describing an individual 262 // namespaced service. The object is built in a manner which would allow us to 263 // add additional fields in the future, if we wanted. 264 type ServiceRegistrationStub struct { 265 ServiceName string 266 Tags []string 267 } 268 269 // ServiceRegistrationByNameRequest is the request object to perform a lookup 270 // of services matching a specific name. 271 type ServiceRegistrationByNameRequest struct { 272 ServiceName string 273 Choose string // stable selection of n services 274 QueryOptions 275 } 276 277 // ServiceRegistrationByNameResponse is the response object when performing a 278 // lookup of services matching a specific name. 279 type ServiceRegistrationByNameResponse struct { 280 Services []*ServiceRegistration 281 QueryMeta 282 }