Skip to content

Commit 8da32eb

Browse files
authored
Merge pull request #123 from tpantelis/fix_two_cluster_export
Ensure first cluster exports service before second cluster
2 parents 07d76f0 + 9ae05f0 commit 8da32eb

File tree

6 files changed

+32
-42
lines changed

6 files changed

+32
-42
lines changed

conformance/clusterip_service_dns.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ import (
3232
var _ = Describe("", Label(OptionalLabel, DNSLabel, ClusterIPLabel), func() {
3333
t := newTestDriver()
3434

35-
JustBeforeEach(func() {
36-
t.createServiceExport(&clients[0], newHelloServiceExport())
37-
})
38-
3935
Specify("A DNS lookup of the <service>.<ns>.svc.clusterset.local domain for a ClusterIP service should resolve to the "+
4036
"clusterset IP", func() {
4137
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#dns")

conformance/conformance_suite.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,11 @@ func setupClients() error {
144144
}
145145

146146
type testDriver struct {
147-
namespace string
148-
helloService *corev1.Service
149-
helloDeployment *appsv1.Deployment
150-
requestPod *corev1.Pod
147+
namespace string
148+
helloService *corev1.Service
149+
helloDeployment *appsv1.Deployment
150+
requestPod *corev1.Pod
151+
autoExportService bool
151152
}
152153

153154
func newTestDriver() *testDriver {
@@ -158,6 +159,7 @@ func newTestDriver() *testDriver {
158159
t.helloService = newHelloService()
159160
t.helloDeployment = newHelloDeployment()
160161
t.requestPod = newRequestPod()
162+
t.autoExportService = true
161163
})
162164

163165
JustBeforeEach(func() {
@@ -178,6 +180,10 @@ func newTestDriver() *testDriver {
178180
for _, client := range clients {
179181
t.startRequestPod(ctx, client)
180182
}
183+
184+
if t.autoExportService {
185+
t.createServiceExport(&clients[0], newHelloServiceExport())
186+
}
181187
})
182188

183189
AfterEach(func() {
@@ -353,11 +359,21 @@ func newTwoClusterTestDriver(t *testDriver) *twoClusterTestDriver {
353359

354360
tt.helloService2 = newHelloService()
355361
tt.helloServiceExport2 = newHelloServiceExport()
362+
t.autoExportService = false
356363
})
357364

358365
JustBeforeEach(func() {
366+
t.createServiceExport(&clients[0], newHelloServiceExport())
367+
368+
// The conflict resolution policy in the MCS spec (KEP 1645) allows an implementation to favor maintaining
369+
// service continuity and avoiding potentially disruptive changes, as such, an implementation may choose the
370+
// first observed exported service when resolving conflicts. To support this, verify the ServiceImport is
371+
// created on the first cluster prior to deploying on the second cluster.
372+
t.awaitServiceImport(&clients[0], helloServiceName, false, nil)
373+
359374
// Delay a little before deploying on the second cluster to ensure the first cluster's ServiceExport timestamp
360-
// is older so conflict checking is deterministic. Make the delay at least 1 sec as creation timestamps have seconds granularity.
375+
// is older so conflict checking is deterministic for implementations that use the timestamp when resolving conflicts.
376+
// Make the delay at least 1 sec as creation timestamps have seconds granularity.
361377
time.Sleep(1100 * time.Millisecond)
362378

363379
t.deployHelloService(&clients[1], tt.helloService2)

conformance/connectivity.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import (
2929
var _ = Describe("", func() {
3030
t := newTestDriver()
3131

32+
BeforeEach(func() {
33+
t.autoExportService = false
34+
})
35+
3236
Context("Connectivity to a service that is not exported", func() {
3337
It("should be inaccessible", Label(RequiredLabel), func() {
3438
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#exporting-services")

conformance/endpoint_slice.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ const K8sEndpointSliceManagedByName = "endpointslice-controller.k8s.io"
3434
var _ = Describe("", Label(OptionalLabel, EndpointSliceLabel), func() {
3535
t := newTestDriver()
3636

37-
JustBeforeEach(func() {
38-
t.createServiceExport(&clients[0], newHelloServiceExport())
39-
})
40-
4137
Specify("Exporting a service should create an MCS EndpointSlice in the service's namespace in each cluster with the "+
4238
"required MCS labels. Unexporting should delete the EndpointSlice.", func() {
4339
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#using-endpointslice-objects-to-track-endpoints")

conformance/headless_service_dns.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ var _ = Describe("", Label(OptionalLabel, DNSLabel, HeadlessLabel), func() {
4545
t.helloDeployment.Spec.Replicas = ptr.To(int32(replicas))
4646
})
4747

48-
JustBeforeEach(func() {
49-
t.createServiceExport(&clients[0], newHelloServiceExport())
50-
})
51-
5248
Specify("A DNS query of the <service>.<ns>.svc.clusterset.local domain for a headless service should return the "+
5349
"ready endpoint addresses of all the backing pods", func() {
5450
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#dns")

conformance/service_import.go

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ func testGeneralServiceImport() {
4444
helloServiceExport = newHelloServiceExport()
4545
})
4646

47-
JustBeforeEach(func() {
48-
t.createServiceExport(&clients[0], helloServiceExport)
49-
})
50-
5147
assertHasKeyValues := func(g Gomega, actual, expected map[string]string) {
5248
for k, v := range expected {
5349
g.Expect(actual).To(HaveKeyWithValue(k, v), reportNonConformant(""))
@@ -148,17 +144,8 @@ func testGeneralServiceImport() {
148144
}
149145

150146
func testClusterIPServiceImport() {
151-
var helloServiceExport *v1alpha1.ServiceExport
152147
t := newTestDriver()
153148

154-
BeforeEach(func() {
155-
helloServiceExport = newHelloServiceExport()
156-
})
157-
158-
JustBeforeEach(func() {
159-
t.createServiceExport(&clients[0], helloServiceExport)
160-
})
161-
162149
Specify("Exporting a ClusterIP service should create a ServiceImport of type ClusterSetIP in the service's namespace in each cluster. "+
163150
"Unexporting should delete the ServiceImport", Label(RequiredLabel), func() {
164151
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#importing-services")
@@ -267,10 +254,6 @@ func testHeadlessServiceImport() {
267254
t.helloService.Spec.ClusterIP = corev1.ClusterIPNone
268255
})
269256

270-
JustBeforeEach(func() {
271-
t.createServiceExport(&clients[0], newHelloServiceExport())
272-
})
273-
274257
Specify("Exporting a headless service should create a ServiceImport of type Headless in the service's namespace in each cluster. "+
275258
"Unexporting should delete the ServiceImport", Label(RequiredLabel), func() {
276259
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#service-types")
@@ -309,10 +292,6 @@ func testExternalNameService() {
309292
t.helloService.Spec.ExternalName = "example.com"
310293
})
311294

312-
JustBeforeEach(func() {
313-
t.createServiceExport(&clients[0], newHelloServiceExport())
314-
})
315-
316295
Specify("Exporting an ExternalName service should set ServiceExport Valid condition to False", Label(RequiredLabel), func() {
317296
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/blob/master/keps/sig-multicluster/1645-multi-cluster-services-api/README.md#service-types")
318297

@@ -329,15 +308,18 @@ func testServiceTypeConflict() {
329308
t.helloService2.Spec.ClusterIP = corev1.ClusterIPNone
330309
})
331310

332-
JustBeforeEach(func() {
333-
t.createServiceExport(&clients[0], newHelloServiceExport())
334-
})
335-
336311
Specify("A service exported on two clusters with conflicting headlessness should apply the conflict resolution policy and "+
337312
"report a Conflict condition on the ServiceExport", Label(RequiredLabel), func() {
338313
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#headlessness")
339314

340315
t.awaitServiceExportCondition(&clients[0], v1alpha1.ServiceExportConditionConflict, metav1.ConditionTrue)
341316
t.awaitServiceExportCondition(&clients[1], v1alpha1.ServiceExportConditionConflict, metav1.ConditionTrue)
317+
318+
for i := range clients {
319+
serviceImport := t.awaitServiceImport(&clients[i], helloServiceName, true, nil)
320+
321+
Expect(serviceImport.Spec.Type).To(Equal(v1alpha1.ClusterSetIP), reportNonConformant(
322+
fmt.Sprintf("ServiceImport on cluster %q has type %q", clients[i].name, serviceImport.Spec.Type)))
323+
}
342324
})
343325
}

0 commit comments

Comments
 (0)