-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathservice_registration.go
157 lines (129 loc) · 4.67 KB
/
service_registration.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package serviceregistration
import (
"context"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/nomad/helper"
"github.com/hashicorp/nomad/nomad/structs"
)
// Handler is the interface the Nomad Client uses to register, update and
// remove services and checks from service registration providers. Currently,
// Consul and Nomad are supported providers.
//
// When utilising Consul, the ACL "service:write" is required. It supports all
// functionality and is the OG/GOAT.
//
// When utilising Nomad, the client secret ID is used for authorisation. It
// currently supports service registrations only.
type Handler interface {
// RegisterWorkload adds all service entries and checks to the backend
// provider. Whilst callers attempt to ensure WorkloadServices.Services is
// not empty before calling this function, implementations should also
// perform this.
RegisterWorkload(workload *WorkloadServices) error
// RemoveWorkload all service entries and checks from the backend provider
// that are found within the passed WorkloadServices object. Whilst callers
// attempt to ensure WorkloadServices.Services is not empty before calling
// this function, implementations should also perform this.
RemoveWorkload(workload *WorkloadServices)
// UpdateWorkload removes workload as specified by the old parameter, and
// adds workload as specified by the new parameter. Callers do not perform
// any deduplication on both objects, it is therefore the responsibility of
// the implementation.
UpdateWorkload(old, newTask *WorkloadServices) error
// AllocRegistrations returns the registrations for the given allocation.
AllocRegistrations(allocID string) (*AllocRegistration, error)
// UpdateTTL is used to update the TTL of an individual service
// registration check.
UpdateTTL(id, namespace, output, status string) error
}
// WorkloadRestarter allows the checkWatcher to restart tasks or entire task
// groups.
type WorkloadRestarter interface {
Restart(ctx context.Context, event *structs.TaskEvent, failure bool) error
}
// AllocRegistration holds the status of services registered for a particular
// allocations by task.
type AllocRegistration struct {
// Tasks maps the name of a task to its registered services and checks.
Tasks map[string]*ServiceRegistrations
}
// Copy performs a deep copy of the AllocRegistration object.
func (a *AllocRegistration) Copy() *AllocRegistration {
c := &AllocRegistration{
Tasks: make(map[string]*ServiceRegistrations, len(a.Tasks)),
}
for k, v := range a.Tasks {
c.Tasks[k] = v.copy()
}
return c
}
// NumServices returns the number of registered services.
func (a *AllocRegistration) NumServices() int {
if a == nil {
return 0
}
total := 0
for _, treg := range a.Tasks {
for _, sreg := range treg.Services {
if sreg.Service != nil {
total++
}
}
}
return total
}
// NumChecks returns the number of registered checks.
func (a *AllocRegistration) NumChecks() int {
if a == nil {
return 0
}
total := 0
for _, treg := range a.Tasks {
for _, sreg := range treg.Services {
total += len(sreg.Checks)
}
}
return total
}
// ServiceRegistrations holds the status of services registered for a
// particular task or task group.
type ServiceRegistrations struct {
Services map[string]*ServiceRegistration
}
func (t *ServiceRegistrations) copy() *ServiceRegistrations {
c := &ServiceRegistrations{
Services: make(map[string]*ServiceRegistration, len(t.Services)),
}
for k, v := range t.Services {
c.Services[k] = v.copy()
}
return c
}
// ServiceRegistration holds the status of a registered Consul Service and its
// Checks.
type ServiceRegistration struct {
// serviceID and checkIDs are internal fields that track just the IDs of the
// services/checks registered in Consul. It is used to materialize the other
// fields when queried.
ServiceID string
CheckIDs map[string]struct{}
// CheckOnUpdate is a map of checkIDs and the associated OnUpdate value
// from the ServiceCheck It is used to determine how a reported checks
// status should be evaluated.
CheckOnUpdate map[string]string
// Service is the AgentService registered in Consul.
Service *api.AgentService
// Checks is the status of the registered checks.
Checks []*api.AgentCheck
}
func (s *ServiceRegistration) copy() *ServiceRegistration {
// Copy does not copy the external fields but only the internal fields.
// This is so that the caller of AllocRegistrations can not access the
// internal fields and that method uses these fields to populate the
// external fields.
return &ServiceRegistration{
ServiceID: s.ServiceID,
CheckIDs: helper.CopyMapStringStruct(s.CheckIDs),
CheckOnUpdate: helper.CopyMapStringString(s.CheckOnUpdate),
}
}