Skip to content

Commit 45ae39b

Browse files
authored
Merge pull request #43 from stakater/shutdownfix
adding shutdown for host cluster to shutdown factory.
2 parents af351da + 31ed48c commit 45ae39b

File tree

6 files changed

+195
-61
lines changed

6 files changed

+195
-61
lines changed

.vscode/launch.json

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
11
{
2-
// Use IntelliSense to learn about possible attributes.
3-
// Hover to view descriptions of existing attributes.
4-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5-
"version": "0.2.0",
6-
"configurations": [
7-
{
8-
"name": "Debug Go Tests",
9-
"type": "go",
10-
"request": "launch",
11-
"mode": "test",
12-
"program": "${fileDirname}", // Specifies that tests in the current directory's package should be run
13-
"args": ["-test.v", "--ginkgo.vv", "--ginkgo.focus", "${selectedText}"], // Verbose test output
14-
"preLaunchTask": "", // This should match the label of your pre-test task
15-
"env": {
16-
"GOFLAGS": "-count=1", // Avoid test caching
17-
},
18-
},
19-
{
20-
"name": "Debug E2E Tests",
21-
"type": "go",
22-
"request": "launch",
23-
"mode": "test",
24-
"program": "${fileDirname}", // Specifies that tests in the current directory's package should be run
25-
"args": ["-test.v", "--ginkgo.vv", "--ginkgo.focus", "${selectedText}"], // Verbose test output
26-
"preLaunchTask": "", // This should match the label of your pre-test task
27-
"env": {
28-
"GOFLAGS": "-count=1", // Avoid test caching
29-
"HOSTED_CLUSTER_NAME": "c7ked5y6v",
30-
"HOSTED_CLUSTER_NAMESPACE": "hypershift-c7ked5y6v",
31-
"SPOKE_ROUTE_NAMESPACE": "openshift-monitoring",
32-
"HUB_NAMESPACE": "c7ked5y6v",
33-
"ROUTE_NAME": "e2e-example-route",
34-
"ROUTE_LABELS": "app=example,env=prod",
35-
"PROBE_JOB_NAME": "e2e-uptime-probe-job",
36-
"PROBE_INTERVAL": "30s",
37-
"PROBE_TIMEOUT": "10s",
38-
"PROBE_MODULE": "http_2xx",
39-
"PROBER_URL": "e2e-blackbox-exporter.openshift-monitoring.svc.cluster.local:9115",
40-
"PROBER_SCHEME": "http",
41-
"PROBER_PATH": "/probe"
42-
},
43-
},
44-
]
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Debug Go Tests",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "test",
12+
"program": "${fileDirname}", // Specifies that tests in the current directory's package should be run
13+
"args": [
14+
"-test.v",
15+
"--ginkgo.vv",
16+
"--ginkgo.focus",
17+
"${selectedText}"
18+
], // Verbose test output
19+
"preLaunchTask": "", // This should match the label of your pre-test task
20+
"env": {
21+
"GOFLAGS": "-count=1", // Avoid test caching
22+
},
23+
},
24+
{
25+
"name": "Debug E2E Tests",
26+
"type": "go",
27+
"request": "launch",
28+
"mode": "test",
29+
"program": "${fileDirname}", // Specifies that tests in the current directory's package should be run
30+
"args": [
31+
"-test.v",
32+
"--ginkgo.vv",
33+
"--ginkgo.focus",
34+
"${selectedText}"
35+
], // Verbose test output
36+
"preLaunchTask": "", // This should match the label of your pre-test task
37+
"env": {
38+
"GOFLAGS": "-count=1", // Avoid test caching
39+
"HOSTED_CLUSTER_NAME": "c7ked5y6v",
40+
"HOSTED_CLUSTER_NAMESPACE": "hypershift-c7ked5y6v",
41+
"SPOKE_ROUTE_NAMESPACE": "openshift-monitoring",
42+
"HUB_NAMESPACE": "c7ked5y6v",
43+
"ROUTE_NAME": "e2e-example-route",
44+
"ROUTE_LABELS": "app=example,env=prod",
45+
"PROBE_JOB_NAME": "e2e-uptime-probe-job",
46+
"PROBE_INTERVAL": "30s",
47+
"PROBE_TIMEOUT": "10s",
48+
"PROBE_MODULE": "http_2xx",
49+
"PROBER_URL": "e2e-blackbox-exporter.openshift-monitoring.svc.cluster.local:9115",
50+
"PROBER_SCHEME": "http",
51+
"PROBER_PATH": "/probe"
52+
},
53+
},
54+
]
4555
}

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ make run
8888
```
8989

9090
**Running E2E Tests:**
91+
92+
Make sure that operator is running
93+
```bash
94+
make run
95+
```
96+
9197
Use the provided VSCode launch configuration to execute the end-to-end tests. The launch file contains the necessary configuration for running tests in your development environment. `Debug E2E Tests` is the launch configuration for running the end-to-end tests. It have environment variables which can be used to configure the test. To run the test in VSCode, you need to select the test name and then click on the `Debug E2E Tests` launch configuration.
9298

9399
If you want to run the test outside of VSCode, you can run the following command (make sure you have all the environment variables set mentioned in the launch configuration `launch.json`):

config/rbac/role.yaml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ rules:
3535
- apiGroups:
3636
- networking.stakater.com
3737
resources:
38-
- routes
38+
- uptimeprobes
3939
verbs:
4040
- create
4141
- delete
@@ -47,26 +47,26 @@ rules:
4747
- apiGroups:
4848
- networking.stakater.com
4949
resources:
50-
- uptimeprobes
50+
- uptimeprobes/finalizers
5151
verbs:
52-
- create
53-
- delete
54-
- get
55-
- list
56-
- patch
5752
- update
58-
- watch
5953
- apiGroups:
6054
- networking.stakater.com
6155
resources:
62-
- uptimeprobes/finalizers
56+
- uptimeprobes/status
6357
verbs:
58+
- get
59+
- patch
6460
- update
6561
- apiGroups:
66-
- networking.stakater.com
62+
- route.openshift.io
6763
resources:
68-
- uptimeprobes/status
64+
- routes
6965
verbs:
66+
- create
67+
- delete
7068
- get
69+
- list
7170
- patch
7271
- update
72+
- watch

internal/controller/spoke_cluster_manager_controller.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
ctrl "sigs.k8s.io/controller-runtime"
1515
"sigs.k8s.io/controller-runtime/pkg/client"
1616
"sigs.k8s.io/controller-runtime/pkg/log"
17+
"sigs.k8s.io/controller-runtime/pkg/manager"
1718
"sigs.k8s.io/controller-runtime/pkg/reconcile"
1819
)
1920

@@ -37,7 +38,7 @@ type SpokeClusterManagerReconciler struct {
3738
//+kubebuilder:rbac:groups=networking.stakater.com,resources=uptimeprobes/finalizers,verbs=update
3839
//+kubebuilder:rbac:groups=hypershift.openshift.io,resources=hostedclusters,verbs=get;list;watch
3940
//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch
40-
//+kubebuilder:rbac:groups=networking.stakater.com,resources=routes,verbs=get;list;watch;create;update;patch;delete
41+
// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete
4142

4243
func (r *SpokeClusterManagerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
4344
r.log = log.FromContext(ctx)
@@ -67,21 +68,21 @@ func (r *SpokeClusterManagerReconciler) Reconcile(ctx context.Context, req ctrl.
6768
return ctrl.Result{}, nil
6869
}
6970

70-
func (r *SpokeClusterManagerReconciler) setupRemoteClientForHostCluster() error {
71+
func (r *SpokeClusterManagerReconciler) setupRemoteClientForHostCluster() (chan struct{}, error) {
7172
if r.RemoteClients == nil {
7273
r.RemoteClients = make(map[string]SpokeManager)
7374
}
7475

7576
if _, ok := r.RemoteClients[clientKey]; ok {
76-
return nil
77+
return nil, nil
7778
}
7879

7980
r.RemoteClients[clientKey] = SpokeManager{
8081
Interface: dynamic.NewForConfigOrDie(r.manager.GetConfig()),
8182
stopInformerChan: make(chan struct{}),
8283
}
8384

84-
return (&SpokeRouteReconciler{
85+
return r.RemoteClients[clientKey].stopInformerChan, (&SpokeRouteReconciler{
8586
Client: r.Client,
8687
RemoteClient: r.RemoteClients[clientKey].Interface,
8788
Scheme: r.Scheme,
@@ -165,11 +166,22 @@ func (r *SpokeClusterManagerReconciler) SetupWithManager(mgr ctrl.Manager) error
165166

166167
r.manager = mgr
167168

168-
err := r.setupRemoteClientForHostCluster()
169+
// setup remote client for host cluster with stop channel
170+
stopChan, err := r.setupRemoteClientForHostCluster()
169171
if err != nil {
170172
return err
171173
}
172174

175+
// Add cleanup to manager
176+
if err := mgr.Add(manager.RunnableFunc(func(ctx context.Context) error {
177+
<-ctx.Done()
178+
delete(r.RemoteClients, clientKey)
179+
close(stopChan)
180+
return nil
181+
})); err != nil {
182+
return err
183+
}
184+
173185
return ctrl.NewControllerManagedBy(mgr).
174186
For(&v1beta1.HostedCluster{}).
175187
Complete(r)

internal/controller/spoke_cluster_manager_controller_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,11 @@ var _ = Describe("SpokeClusterManagerController", func() {
240240
reconciler.RemoteClients[clientKey] = mockSpokeManager
241241

242242
// Try to setup host client again
243-
err := reconciler.setupRemoteClientForHostCluster()
243+
_, err := reconciler.setupRemoteClientForHostCluster()
244244
Expect(err).NotTo(HaveOccurred())
245245

246246
// Verify the original client was not replaced
247-
hostClient := reconciler.RemoteClients["host"]
247+
hostClient := reconciler.RemoteClients[clientKey]
248248
Expect(hostClient).To(Equal(mockSpokeManager))
249249
})
250250
})

test/e2e/e2e_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,4 +519,110 @@ var _ = Describe("UptimeGuardian E2E", Ordered, func() {
519519
}, timeout, interval).Should(Succeed())
520520
})
521521
})
522+
523+
Context("When testing host cluster route monitoring", func() {
524+
var (
525+
uptimeProbe *v1alpha1.UptimeProbe
526+
skipCleanup bool
527+
hubDynamicClient dynamic.Interface
528+
)
529+
530+
BeforeEach(func() {
531+
skipCleanup = false
532+
533+
// Create dynamic client for host cluster
534+
config, err := utils.GetKubeConfigFromEnv()
535+
Expect(err).NotTo(HaveOccurred(), "Should get kubeconfig")
536+
537+
hubDynamicClient, err = dynamic.NewForConfig(config)
538+
Expect(err).NotTo(HaveOccurred(), "Should create dynamic client")
539+
540+
// Create UptimeProbe for host cluster
541+
uptimeProbe = &v1alpha1.UptimeProbe{
542+
ObjectMeta: metav1.ObjectMeta{
543+
Name: "e2e-test-host-uptime-probe",
544+
Namespace: hubNamespace,
545+
},
546+
Spec: v1alpha1.UptimeProbeSpec{
547+
LabelSelector: metav1.LabelSelector{
548+
MatchLabels: map[string]string{"monitor": "host"},
549+
},
550+
ProbeConfig: v1alpha1.ProbeConfig{
551+
JobName: "host-" + probeJobName,
552+
Interval: monitoringv1.Duration(probeInterval),
553+
Module: probeModule,
554+
ScrapeTimeout: monitoringv1.Duration(probeScrapeTimeout),
555+
ProberUrl: proberUrl,
556+
ProberScheme: proberScheme,
557+
ProberPath: proberPath,
558+
TargetNamespace: hubNamespace,
559+
},
560+
},
561+
}
562+
})
563+
564+
AfterEach(func() {
565+
if skipCleanup {
566+
return
567+
}
568+
// Cleanup
569+
Expect(k8sClient.Delete(ctx, uptimeProbe)).Should(Succeed())
570+
571+
// Delete test routes
572+
_ = hubDynamicClient.Resource(getRouteGVR()).Namespace(hubNamespace).Delete(ctx, "host-route", metav1.DeleteOptions{})
573+
})
574+
575+
It("should monitor host cluster routes", func() {
576+
By("Creating route in host cluster")
577+
hostLabels := map[string]string{"monitor": "host"}
578+
err := createTestRoutes(ctx, hubDynamicClient, hubNamespace, "host-route", hostLabels)
579+
Expect(err).NotTo(HaveOccurred())
580+
581+
By("Creating UptimeProbe for host routes")
582+
Expect(k8sClient.Create(ctx, uptimeProbe)).Should(Succeed())
583+
584+
By("Verifying Probe CR is created with correct name format")
585+
Eventually(func() error {
586+
probe := &monitoringv1.Probe{}
587+
return k8sClient.Get(ctx, types.NamespacedName{
588+
Name: fmt.Sprintf("%s-%s-%s", "host", hubNamespace, "host-route"),
589+
Namespace: hubNamespace,
590+
}, probe)
591+
}, timeout, interval).Should(Succeed())
592+
593+
By("Verifying Probe CR has correct configuration")
594+
probe := &monitoringv1.Probe{}
595+
err = k8sClient.Get(ctx, types.NamespacedName{
596+
Name: fmt.Sprintf("%s-%s-%s", "host", hubNamespace, "host-route"),
597+
Namespace: hubNamespace,
598+
}, probe)
599+
Expect(err).NotTo(HaveOccurred())
600+
Expect(probe.Spec.JobName).To(Equal("host-" + probeJobName))
601+
Expect(string(probe.Spec.Interval)).To(Equal(probeInterval))
602+
Expect(probe.Spec.Module).To(Equal(probeModule))
603+
})
604+
605+
It("should handle route deletion in host cluster", func() {
606+
By("Creating route in host cluster")
607+
hostLabels := map[string]string{"monitor": "host"}
608+
err := createTestRoutes(ctx, hubDynamicClient, hubNamespace, "host-route", hostLabels)
609+
Expect(err).NotTo(HaveOccurred())
610+
611+
By("Creating UptimeProbe for host routes")
612+
Expect(k8sClient.Create(ctx, uptimeProbe)).Should(Succeed())
613+
614+
By("Deleting the route")
615+
err = hubDynamicClient.Resource(getRouteGVR()).Namespace(hubNamespace).Delete(ctx, "host-route", metav1.DeleteOptions{})
616+
Expect(err).NotTo(HaveOccurred())
617+
618+
By("Verifying Probe CR is removed")
619+
Eventually(func() error {
620+
probe := &monitoringv1.Probe{}
621+
return k8sClient.Get(ctx, types.NamespacedName{
622+
Name: fmt.Sprintf("%s-%s-%s", "host", hubNamespace, "host-route"),
623+
Namespace: hubNamespace,
624+
}, probe)
625+
}, timeout, interval).Should(HaveOccurred())
626+
})
627+
})
522628
})

0 commit comments

Comments
 (0)