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