Skip to content

Commit 7a4877c

Browse files
authored
Add ServiceType to Cloud Map and Endpoints (#170)
1 parent 535a92c commit 7a4877c

File tree

8 files changed

+91
-7
lines changed

8 files changed

+91
-7
lines changed

integration/shared/scenarios/export_service.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func NewExportServiceScenario(cfg *aws.Config, nsName string, svcName string, po
5858
Protocol: string(v1.ProtocolTCP),
5959
},
6060
EndpointPort: endpointPort,
61+
ServiceType: model.ClusterSetIPType, // in scenario, we assume ClusterSetIP type
6162
Attributes: make(map[string]string),
6263
})
6364
}

pkg/cloudmap/client_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ func TestServiceDiscoveryClient_RegisterEndpoints(t *testing.T) {
291291
model.ServicePortAttr: test.ServicePortStr1,
292292
model.ServiceProtocolAttr: test.Protocol1,
293293
model.ServiceTargetPortAttr: test.PortStr1,
294+
model.ServiceTypeAttr: test.SvcType,
294295
}
295296
attrs2 := map[string]string{
296297
model.EndpointIpv4Attr: test.EndptIp2,
@@ -301,6 +302,7 @@ func TestServiceDiscoveryClient_RegisterEndpoints(t *testing.T) {
301302
model.ServicePortAttr: test.ServicePortStr2,
302303
model.ServiceProtocolAttr: test.Protocol2,
303304
model.ServiceTargetPortAttr: test.PortStr2,
305+
model.ServiceTypeAttr: test.SvcType,
304306
}
305307

306308
tc.mockApi.EXPECT().RegisterInstance(context.TODO(), test.SvcId, test.EndptId1, attrs1).
@@ -370,6 +372,7 @@ func getHttpInstanceSummaryForTest() []types.HttpInstanceSummary {
370372
model.ServicePortAttr: test.ServicePortStr1,
371373
model.ServiceProtocolAttr: test.Protocol1,
372374
model.ServiceTargetPortAttr: test.PortStr1,
375+
model.ServiceTypeAttr: test.SvcType,
373376
},
374377
},
375378
{
@@ -383,6 +386,7 @@ func getHttpInstanceSummaryForTest() []types.HttpInstanceSummary {
383386
model.ServicePortAttr: test.ServicePortStr2,
384387
model.ServiceProtocolAttr: test.Protocol2,
385388
model.ServiceTargetPortAttr: test.PortStr2,
389+
model.ServiceTypeAttr: test.SvcType,
386390
},
387391
},
388392
}

pkg/controllers/multicluster/serviceexport_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ func (r *ServiceExportReconciler) extractEndpoints(ctx context.Context, svc *v1.
225225
return nil, err
226226
}
227227

228+
serviceType := ExtractServiceType(svc)
229+
228230
servicePortMap := make(map[string]model.Port)
229231
for _, svcPort := range svc.Spec.Ports {
230232
servicePortMap[svcPort.Name] = ServicePortToPort(svcPort)
@@ -249,6 +251,7 @@ func (r *ServiceExportReconciler) extractEndpoints(ctx context.Context, svc *v1.
249251
IP: IP,
250252
EndpointPort: port,
251253
ServicePort: servicePortMap[*endpointPort.Name],
254+
ServiceType: serviceType,
252255
Attributes: attributes,
253256
})
254257
}

pkg/controllers/multicluster/utils.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,12 @@ func CreateEndpointSliceStruct(svc *v1.Service, svcImportName string) *discovery
226226
AddressType: discovery.AddressTypeIPv4,
227227
}
228228
}
229+
230+
// ExtractServiceType finds the ServiceType of a given service as Headless/ClusterSetIP
231+
func ExtractServiceType(svc *v1.Service) model.ServiceType {
232+
if svc.Spec.ClusterIP == "None" {
233+
return model.HeadlessType
234+
}
235+
236+
return model.ClusterSetIPType
237+
}

pkg/model/types.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,20 @@ type Service struct {
3333
Endpoints []*Endpoint
3434
}
3535

36+
const (
37+
HeadlessType ServiceType = "Headless"
38+
ClusterSetIPType ServiceType = "ClusterSetIP"
39+
)
40+
41+
type ServiceType string
42+
3643
// Endpoint holds basic values and attributes for an endpoint.
3744
type Endpoint struct {
3845
Id string
3946
IP string
4047
EndpointPort Port
4148
ServicePort Port
49+
ServiceType ServiceType
4250
Attributes map[string]string
4351
}
4452

@@ -60,10 +68,11 @@ const (
6068
ServicePortAttr = "SERVICE_PORT"
6169
ServiceTargetPortAttr = "SERVICE_TARGET_PORT"
6270
ServiceProtocolAttr = "SERVICE_PROTOCOL"
71+
ServiceTypeAttr = "SERVICE_TYPE"
6372
)
6473

6574
// NewEndpointFromInstance converts a Cloud Map HttpInstanceSummary to an endpoint.
66-
func NewEndpointFromInstance(inst *types.HttpInstanceSummary) (endpointPtr *Endpoint, err error) {
75+
func NewEndpointFromInstance(inst *types.HttpInstanceSummary) (*Endpoint, error) {
6776
endpoint := Endpoint{
6877
Id: *inst.InstanceId,
6978
Attributes: make(map[string]string),
@@ -73,18 +82,30 @@ func NewEndpointFromInstance(inst *types.HttpInstanceSummary) (endpointPtr *Endp
7382
attributes[key] = value
7483
}
7584

76-
// Remove and set the IP, Port, Port
77-
if endpoint.IP, err = removeStringAttr(attributes, EndpointIpv4Attr); err != nil {
85+
// Remove and set the IP, Port, Service Port, ServiceType
86+
ip, err := removeStringAttr(attributes, EndpointIpv4Attr)
87+
if err != nil {
7888
return nil, err
7989
}
90+
endpoint.IP = ip
8091

81-
if endpoint.EndpointPort, err = endpointPortFromAttr(attributes); err != nil {
92+
endpointPort, err := endpointPortFromAttr(attributes)
93+
if err != nil {
8294
return nil, err
8395
}
96+
endpoint.EndpointPort = endpointPort
8497

85-
if endpoint.ServicePort, err = servicePortFromAttr(attributes); err != nil {
98+
servicePort, err := servicePortFromAttr(attributes)
99+
if err != nil {
86100
return nil, err
87101
}
102+
endpoint.ServicePort = servicePort
103+
104+
serviceTypeStr, err := removeStringAttr(attributes, ServiceTypeAttr)
105+
if err != nil {
106+
return nil, err
107+
}
108+
endpoint.ServiceType = ServiceType(serviceTypeStr)
88109

89110
// Add the remaining attributes
90111
endpoint.Attributes = attributes
@@ -156,6 +177,7 @@ func (e *Endpoint) GetCloudMapAttributes() map[string]string {
156177
attrs[ServicePortAttr] = strconv.Itoa(int(e.ServicePort.Port))
157178
attrs[ServiceTargetPortAttr] = e.ServicePort.TargetPort
158179
attrs[ServiceProtocolAttr] = e.ServicePort.Protocol
180+
attrs[ServiceTypeAttr] = e.ServiceType.String()
159181

160182
for key, val := range e.Attributes {
161183
attrs[key] = val
@@ -186,6 +208,11 @@ func EndpointIdFromIPAddressAndPort(address string, port Port) string {
186208
return fmt.Sprintf("%s-%s-%d", strings.ToLower(port.Protocol), address, port.Port)
187209
}
188210

211+
// Gives string representation for ServiceType
212+
func (serviceType ServiceType) String() string {
213+
return string(serviceType)
214+
}
215+
189216
func ConvertNamespaceType(nsType types.NamespaceType) (namespaceType NamespaceType) {
190217
switch nsType {
191218
case types.NamespaceTypeDnsPrivate:

pkg/model/types_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
var instId = "my-instance"
1111
var ip = "192.168.0.1"
12+
var serviceType = ClusterSetIPType.String()
1213

1314
func TestNewEndpointFromInstance(t *testing.T) {
1415
tests := []struct {
@@ -30,6 +31,7 @@ func TestNewEndpointFromInstance(t *testing.T) {
3031
ServiceProtocolAttr: "TCP",
3132
ServicePortAttr: "65535",
3233
ServiceTargetPortAttr: "80",
34+
ServiceTypeAttr: serviceType,
3335
"custom-attr": "custom-val",
3436
},
3537
},
@@ -47,6 +49,7 @@ func TestNewEndpointFromInstance(t *testing.T) {
4749
TargetPort: "80",
4850
Protocol: "TCP",
4951
},
52+
ServiceType: ServiceType(serviceType),
5053
Attributes: map[string]string{
5154
"custom-attr": "custom-val",
5255
},
@@ -65,6 +68,7 @@ func TestNewEndpointFromInstance(t *testing.T) {
6568
ServiceProtocolAttr: "TCP",
6669
ServicePortAttr: "99999",
6770
ServiceTargetPortAttr: "80",
71+
ServiceTypeAttr: serviceType,
6872
"custom-attr": "custom-val",
6973
},
7074
},
@@ -92,6 +96,24 @@ func TestNewEndpointFromInstance(t *testing.T) {
9296
},
9397
wantErr: true,
9498
},
99+
{
100+
name: "missing ServiceType",
101+
inst: &types.HttpInstanceSummary{
102+
InstanceId: &instId,
103+
Attributes: map[string]string{
104+
EndpointIpv4Attr: ip,
105+
EndpointPortAttr: "80",
106+
EndpointProtocolAttr: "TCP",
107+
EndpointPortNameAttr: "http",
108+
ServicePortNameAttr: "http",
109+
ServiceProtocolAttr: "TCP",
110+
ServicePortAttr: "65535",
111+
ServiceTargetPortAttr: "80",
112+
"custom-attr": "custom-val",
113+
},
114+
},
115+
wantErr: true,
116+
},
95117
}
96118
for _, tt := range tests {
97119
t.Run(tt.name, func(t *testing.T) {
@@ -113,6 +135,7 @@ func TestEndpoint_GetAttributes(t *testing.T) {
113135
IP string
114136
EndpointPort Port
115137
ServicePort Port
138+
ServiceType ServiceType
116139
Attributes map[string]string
117140
}
118141
tests := []struct {
@@ -135,6 +158,7 @@ func TestEndpoint_GetAttributes(t *testing.T) {
135158
TargetPort: "80",
136159
Protocol: "TCP",
137160
},
161+
ServiceType: ServiceType(serviceType),
138162
Attributes: map[string]string{
139163
"custom-attr": "custom-val",
140164
},
@@ -148,6 +172,7 @@ func TestEndpoint_GetAttributes(t *testing.T) {
148172
ServiceProtocolAttr: "TCP",
149173
ServicePortAttr: "30",
150174
ServiceTargetPortAttr: "80",
175+
ServiceTypeAttr: serviceType,
151176
"custom-attr": "custom-val",
152177
},
153178
},
@@ -159,6 +184,7 @@ func TestEndpoint_GetAttributes(t *testing.T) {
159184
IP: tt.fields.IP,
160185
EndpointPort: tt.fields.EndpointPort,
161186
ServicePort: tt.fields.ServicePort,
187+
ServiceType: tt.fields.ServiceType,
162188
Attributes: tt.fields.Attributes,
163189
}
164190
if got := e.GetCloudMapAttributes(); !reflect.DeepEqual(got, tt.want) {

samples/example-headless.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
kind: Service
2+
apiVersion: v1
3+
metadata:
4+
namespace: example
5+
name: my-service
6+
spec:
7+
clusterIP: None
8+
selector:
9+
app: nginx
10+
ports:
11+
- port: 80

test/test-constants.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const (
3232
OpId1 = "operation-id-1"
3333
OpId2 = "operation-id-2"
3434
OpStart = 1
35+
SvcType = "ClusterSetIP"
3536
)
3637

3738
func GetTestHttpNamespace() *model.Namespace {
@@ -81,7 +82,8 @@ func GetTestEndpoint1() *model.Endpoint {
8182
TargetPort: PortStr1,
8283
Protocol: Protocol1,
8384
},
84-
Attributes: make(map[string]string),
85+
ServiceType: model.ClusterSetIPType,
86+
Attributes: make(map[string]string),
8587
}
8688
}
8789

@@ -100,7 +102,8 @@ func GetTestEndpoint2() *model.Endpoint {
100102
TargetPort: PortStr2,
101103
Protocol: Protocol2,
102104
},
103-
Attributes: make(map[string]string),
105+
ServiceType: model.ClusterSetIPType,
106+
Attributes: make(map[string]string),
104107
}
105108
}
106109

0 commit comments

Comments
 (0)