Skip to content

Commit 9057a2d

Browse files
mikeshngMagic Mirror
authored andcommitted
feat: Add an annotation to allow for hub appsub bypassing Git clone operations to speed up appsub propagation to managed cluster (#431)
Signed-off-by: Mike Ng <ming@redhat.com> (cherry picked from commit 1c7c4c9a00df998c16a6e9713077d6ae4e035982)
1 parent 97795fc commit 9057a2d

File tree

10 files changed

+162
-23
lines changed

10 files changed

+162
-23
lines changed

build/e2e-kc.sh

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,38 @@ else
3939
exit 1
4040
fi
4141

42+
### 000-git-skip-clone
43+
echo "STARTING test 000-git-skip-clone"
44+
kubectl config use-context kind-hub
45+
kubectl apply -f test/e2e/cases/000-git-skip-clone/
46+
sleep 20
47+
if kubectl get subscriptions.apps.open-cluster-management.io git-hub-skip-clone | grep Propagated; then
48+
echo "000-git-skip-clone: hub subscriptions.apps.open-cluster-management.io status is Propagated"
49+
else
50+
echo "000-git-skip-clone FAILED: hub subscriptions.apps.open-cluster-management.io status is not Propagated"
51+
exit 1
52+
fi
53+
54+
kubectl config use-context kind-cluster1
55+
if kubectl get subscriptions.apps.open-cluster-management.io git-hub-skip-clone | grep Subscribed; then
56+
echo "000-git-skip-clone: cluster1 subscriptions.apps.open-cluster-management.io status is Subscribed"
57+
else
58+
echo "000-git-skip-clone FAILED: cluster1 subscriptions.apps.open-cluster-management.io status is not Subscribed"
59+
exit 1
60+
fi
61+
62+
if kubectl get clusterrole | grep psp | grep rook; then
63+
echo "000-git-skip-clone: git manifest clusterrole is applied on the managed cluster"
64+
else
65+
echo "000-git-skip-clone FAILED: git manifest clusterrole is not applied on the managed cluster"
66+
exit 1
67+
fi
68+
69+
kubectl config use-context kind-hub
70+
kubectl delete -f test/e2e/cases/000-git-skip-clone/
71+
echo "PASSED test case 000-git-skip-clone"
72+
sleep 10
73+
4274
### 00-helm-semver
4375
echo "STARTING test case 00-helm-semver"
4476
kubectl config use-context kind-hub
@@ -49,6 +81,7 @@ else
4981
exit 1
5082
fi
5183
kubectl delete -f test/e2e/cases/00-helm-semver/semver_appsub.yaml
84+
echo "PASSED test case 00-helm-semver"
5285
sleep 10
5386

5487
### 01-placement
@@ -57,7 +90,7 @@ kubectl config use-context kind-hub
5790
kubectl label managedcluster cluster1 cluster.open-cluster-management.io/clusterset=app-demo --overwrite
5891
kubectl label managedcluster cluster1 purpose=test --overwrite
5992
kubectl apply -f test/e2e/cases/01-placement/
60-
sleep 30
93+
sleep 20
6194

6295
if kubectl get subscriptions.apps.open-cluster-management.io ingress | grep Propagated; then
6396
echo "01-placement: hub subscriptions.apps.open-cluster-management.io status is Propagated"
@@ -90,7 +123,7 @@ fi
90123

91124
kubectl config use-context kind-hub
92125
kubectl delete -f test/e2e/cases/01-placement/
93-
sleep 30
126+
sleep 20
94127
kubectl config use-context kind-cluster1
95128
if kubectl get pod | grep ingress; then
96129
echo "01-placement FAILED: appsub deployment pod is not deleted"
@@ -104,7 +137,7 @@ echo "PASSED test case 01-placement"
104137
echo "STARTING test 02-placementrule"
105138
kubectl config use-context kind-hub
106139
kubectl apply -f test/e2e/cases/02-placementrule/
107-
sleep 30
140+
sleep 20
108141

109142
if kubectl get subscriptions.apps.open-cluster-management.io ingress | grep Propagated; then
110143
echo "02-placementrule: hub subscriptions.apps.open-cluster-management.io status is Propagated"
@@ -137,7 +170,7 @@ fi
137170

138171
kubectl config use-context kind-hub
139172
kubectl delete -f test/e2e/cases/02-placementrule/
140-
sleep 30
173+
sleep 20
141174
kubectl config use-context kind-cluster1
142175
if kubectl get pod | grep ingress; then
143176
echo "02-placementrule FAILED: appsub deployment pod is not deleted"
@@ -152,7 +185,7 @@ echo "STARTING test 03-keep-namespace"
152185
kubectl config use-context kind-hub
153186
kubectl create ns test-case-03
154187
kubectl apply -f test/e2e/cases/03-keep-namespace/
155-
sleep 30
188+
sleep 20
156189

157190
kubectl config use-context kind-cluster1
158191
if kubectl get ns test-case-03; then
@@ -164,7 +197,7 @@ fi
164197

165198
kubectl config use-context kind-hub
166199
kubectl delete -f test/e2e/cases/03-keep-namespace/
167-
sleep 30
200+
sleep 20
168201
kubectl config use-context kind-cluster1
169202
if kubectl get ns test-case-03; then
170203
echo "03-keep-namespace: cluster1 namespace 03-keep-namespace is still present"
@@ -256,7 +289,7 @@ echo "PASSED test case 06-ansiblejob-post"
256289
echo "STARTING test case 07-helm-install-error"
257290
kubectl config use-context kind-hub
258291
kubectl apply -f test/e2e/cases/07-helm-install-error/
259-
sleep 30
292+
sleep 20
260293
kubectl config use-context kind-cluster1
261294
if kubectl get subscriptionstatus.apps.open-cluster-management.io ingress -o yaml | grep "phase: Failed"; then
262295
echo "07-helm-install-error: found failed phase in subscription status output"
@@ -273,7 +306,7 @@ echo "PASSED test case 07-helm-install-error"
273306
echo "STARTING test case 08-helm-upgrade-error"
274307
kubectl config use-context kind-hub
275308
kubectl apply -f test/e2e/cases/08-helm-upgrade-error/install
276-
sleep 30
309+
sleep 20
277310
kubectl config use-context kind-cluster1
278311
if kubectl get subscriptionstatus.apps.open-cluster-management.io ingress -o yaml | grep "phase: Deployed"; then
279312
echo "08-helm-upgrade-error: found deployed phase in subscription status output"
@@ -302,7 +335,7 @@ echo "PASSED test case 08-helm-upgrade-error"
302335
echo "STARTING test case 09-helm-missing-phase"
303336
kubectl config use-context kind-hub
304337
kubectl apply -f test/e2e/cases/09-helm-missing-phase/
305-
sleep 30
338+
sleep 20
306339
kubectl config use-context kind-cluster1
307340
if kubectl get subscriptionstatus.apps.open-cluster-management.io preinstall-hook -o yaml | grep "kind: Deployment"; then
308341
echo "09-helm-missing-phase: found deployment kind in subscription status output"
@@ -324,7 +357,7 @@ echo "PASSED test case 09-helm-missing-phase"
324357
echo "STARTING test 10-cluster-override-ns"
325358
kubectl config use-context kind-hub
326359
kubectl apply -f test/e2e/cases/10-cluster-override-ns/
327-
sleep 30
360+
sleep 20
328361
kubectl config use-context kind-cluster1
329362
if kubectl -n test-10 get pod | grep nginx-placement | grep Running; then
330363
echo "10-cluster-override-ns: appsub deployment pod status is Running"
@@ -334,7 +367,7 @@ else
334367
fi
335368
kubectl config use-context kind-hub
336369
kubectl delete -f test/e2e/cases/10-cluster-override-ns/
337-
sleep 30
370+
sleep 20
338371
kubectl config use-context kind-cluster1
339372
if kubectl -n test-10 get pod | grep nginx-placement; then
340373
echo "10-cluster-override-ns FAILED: appsub deployment pod is not deleted"
@@ -348,14 +381,14 @@ echo "PASSED test case 10-cluster-override-ns"
348381
echo "STARTING test 11-helm-hub-dryrun"
349382
kubectl config use-context kind-hub
350383
kubectl apply -f test/e2e/cases/11-helm-hub-dryrun/
351-
sleep 30
384+
sleep 20
352385
if kubectl get subscriptions.apps.open-cluster-management.io -n default ingress-appsub | grep Propagated; then
353386
echo "11-helm-hub-dryrun: ingress-appsub status is Propagated"
354387
else
355388
echo "11-helm-hub-dryruns FAILED: ingress-appsub status is not Propagated"
356389
exit 1
357390
fi
358-
sleep 30
391+
sleep 20
359392
kubectl config use-context kind-cluster1
360393

361394
RUN_CMD="kubectl get subscriptionstatus.apps.open-cluster-management.io -n default ingress-appsub"
@@ -382,7 +415,7 @@ echo "PASSED test case 11-helm-hub-dryrun"
382415
echo "STARTING test 12-helm-update"
383416
kubectl config use-context kind-hub
384417
kubectl apply -f test/e2e/cases/12-helm-update/install
385-
sleep 30
418+
sleep 20
386419
if kubectl get subscriptions.apps.open-cluster-management.io ingress | grep Propagated; then
387420
echo "12-helm-update: ingress status is Propagated"
388421
else
@@ -419,7 +452,7 @@ echo "PASSED test case 12-helm-update"
419452
echo "STARTING test 13-git-res-name"
420453
kubectl config use-context kind-hub
421454
kubectl apply -f test/e2e/cases/13-git-res-name/
422-
sleep 30
455+
sleep 20
423456
if kubectl get subscriptions.apps.open-cluster-management.io git-app-sub | grep Propagated; then
424457
echo "13-git-res-name: hub subscriptions.apps.open-cluster-management.io status is Propagated"
425458
else
@@ -433,7 +466,7 @@ echo "PASSED test case 13-git-res-name"
433466
echo "STARTING test 14-helm-appsubstatus"
434467
kubectl config use-context kind-hub
435468
kubectl apply -f test/e2e/cases/14-helm-appsubstatus/install
436-
sleep 30
469+
sleep 20
437470
if kubectl get subscriptionreport.apps.open-cluster-management.io ingress | grep ingress; then
438471
echo "14-helm-appsubstatus: ingress subscriptionreport is found"
439472
else
@@ -474,7 +507,7 @@ echo "PASSED test case 14-helm-appsubstatus"
474507
echo "STARTING test 15-git-helm"
475508
kubectl config use-context kind-hub
476509
kubectl apply -f test/e2e/cases/15-git-helm/install
477-
sleep 30
510+
sleep 20
478511
if kubectl get subscriptions.apps.open-cluster-management.io git-app-sub | grep Propagated; then
479512
echo "15-git-helm: hub subscriptions.apps.open-cluster-management.io status is Propagated"
480513
else
@@ -498,7 +531,7 @@ echo "PASSED test case 15-git-helm"
498531
echo "STARTING test 16-helm-recreate"
499532
kubectl config use-context kind-hub
500533
kubectl apply -f test/e2e/cases/16-helm-recreate
501-
sleep 30
534+
sleep 20
502535
if kubectl get subscriptions.apps.open-cluster-management.io ingress | grep Propagated; then
503536
echo "16-helm-recreate: ingress status is Propagated"
504537
else
@@ -605,7 +638,7 @@ echo "19-verify-git-pull-time-metric: patching successful subscription and expet
605638
kubectl config use-context kind-hub
606639
kubectl apply -f test/e2e/cases/19-verify-git-pull-time-metric/failed
607640
# deliver an appsub with invalid channel info, it is expected to get the failure once the appsub is deployed on the managed cluster
608-
sleep 30
641+
sleep 20
609642

610643
echo "19-verify-git-pull-time-metric: fetching failed managed cluster metrics"
611644
kubectl config use-context kind-cluster1
@@ -644,7 +677,7 @@ kubectl apply -f test/e2e/cases/20-verify-propagation-time-metric/failed-no-plac
644677
kubectl apply -f test/e2e/cases/20-verify-propagation-time-metric/failed-placement-wrong
645678
kubectl apply -f test/e2e/cases/20-verify-propagation-time-metric/standalone
646679
kubectl apply -f test/e2e/cases/20-verify-propagation-time-metric/successful
647-
sleep 30
680+
sleep 20
648681

649682
echo "20-verify-propagation-time-metric: fetching collected hub cluster metrics"
650683
collectedMcMetrics=`kubectl exec -n open-cluster-management deploy/multicluster-operators-subscription -- curl http://localhost:8381/metrics`
@@ -692,7 +725,7 @@ kubectl label managedcluster cluster1 cluster.open-cluster-management.io/cluster
692725
kubectl label managedcluster cluster1 purpose=test --overwrite
693726

694727
kubectl apply -f test/e2e/cases/21-verify-local-deployment-time-metric
695-
sleep 30
728+
sleep 20
696729

697730
kubectl config use-context kind-cluster1
698731
kubectl -n local-deployment-metric-test rollout status deployment/git-simple-subscription

pkg/apis/apps/v1/subscription_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ var (
9696
AnnotationHostingDeployable = SchemeGroupVersion.Group + "/hosting-deployable"
9797
// AnnotationCurrentNamespaceScoped specifies to deloy resources into subscription namespace
9898
AnnotationCurrentNamespaceScoped = SchemeGroupVersion.Group + "/current-namespace-scoped"
99+
// AnnotationSkipHubValidation indicates the hub subscription should skip the "dry-run" validations and proceed to propagation phase
100+
AnnotationSkipHubValidation = SchemeGroupVersion.Group + "/skip-hub-validation"
99101
)
100102

101103
const (

pkg/controller/mcmhub/hub.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ func (r *ReconcileSubscription) doMCMHubReconcile(sub *appv1.Subscription) error
9393
// Add or sync application labels
9494
r.AddAppLabels(sub)
9595

96+
// Skip fetching resources and creating appsub report if skip hub validation is true
97+
if shouldSkipHubValidation(sub) {
98+
clusters, err := r.getClustersByPlacement(sub)
99+
if err != nil {
100+
klog.Error("Error in getting clusters:", err)
101+
return err
102+
}
103+
104+
return r.PropagateAppSubManifestWork(sub, clusters)
105+
}
106+
96107
var resources []*v1.ObjectReference
97108

98109
switch tp := strings.ToLower(string(primaryChannel.Spec.Type)); tp {

pkg/controller/mcmhub/hub_git.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ func (h *HubGitOps) RegisterBranch(subIns *subv1.Subscription) error {
342342
h.logger.Info("entry register branch for appsub " + subIns.Namespace + "/" + subIns.Name)
343343
defer h.logger.Info("exit register branch for appsub " + subIns.Namespace + "/" + subIns.Name)
344344

345+
if shouldSkipHubValidation(subIns) {
346+
h.logger.Info("skipping register branch for appsub " + subIns.Namespace + "/" + subIns.Name)
347+
return nil
348+
}
349+
345350
subKey := types.NamespacedName{Name: subIns.GetName(), Namespace: subIns.GetNamespace()}
346351

347352
// This does not pick up new changes to channel configuration
@@ -781,3 +786,12 @@ func (h *HubGitOps) GetHooks(subIns *subv1.Subscription, hookPath string) ([]ans
781786

782787
return newAnsibleJobs, nil
783788
}
789+
790+
func shouldSkipHubValidation(subIns *subv1.Subscription) bool {
791+
annos := subIns.GetAnnotations()
792+
if len(annos) > 0 && annos[subv1.AnnotationSkipHubValidation] == "true" {
793+
return true
794+
}
795+
796+
return false
797+
}

pkg/controller/mcmhub/hub_git_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,50 @@ var _ = PDescribe("hub git ops", func() {
431431
Eventually(detectTargetCommit(subKey, defaultCommit), specTimeOut, pullInterval).Should(Succeed())
432432
})
433433
})
434+
435+
var _ = Describe("shouldSkipHubValidation", func() {
436+
var (
437+
sub *subv1.Subscription
438+
)
439+
BeforeEach(func() {
440+
sub = &subv1.Subscription{
441+
ObjectMeta: metav1.ObjectMeta{
442+
Name: "test-sub",
443+
Namespace: "default",
444+
},
445+
}
446+
})
447+
It("should return false when annotation is nil", func() {
448+
Expect(shouldSkipHubValidation(sub)).To(BeFalse())
449+
})
450+
It("should return false when skip annotation is missing", func() {
451+
sub.SetAnnotations(map[string]string{
452+
"foobar": "true",
453+
})
454+
Expect(shouldSkipHubValidation(sub)).To(BeFalse())
455+
})
456+
It("should return true when skip annotation is true'", func() {
457+
sub.SetAnnotations(map[string]string{
458+
subv1.AnnotationSkipHubValidation: "true",
459+
})
460+
Expect(shouldSkipHubValidation(sub)).To(BeTrue())
461+
})
462+
It("should return false when skip annotation is empty", func() {
463+
sub.SetAnnotations(map[string]string{
464+
subv1.AnnotationSkipHubValidation: "",
465+
})
466+
Expect(shouldSkipHubValidation(sub)).To(BeFalse())
467+
})
468+
It("should return false when skip annotation is false", func() {
469+
sub.SetAnnotations(map[string]string{
470+
subv1.AnnotationSkipHubValidation: "false",
471+
})
472+
Expect(shouldSkipHubValidation(sub)).To(BeFalse())
473+
})
474+
It("should return false when skip annotation is non boolean string values", func() {
475+
sub.SetAnnotations(map[string]string{
476+
subv1.AnnotationSkipHubValidation: "foobar",
477+
})
478+
Expect(shouldSkipHubValidation(sub)).To(BeFalse())
479+
})
480+
})
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: apps.open-cluster-management.io/v1
2+
kind: Channel
3+
metadata:
4+
name: gitops
5+
namespace: default
6+
annotations:
7+
apps.open-cluster-management.io/reconcile-rate: high
8+
spec:
9+
pathname: 'https://github.com/open-cluster-management-io/multicloud-operators-subscription.git'
10+
type: Git
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: apps.open-cluster-management.io/v1
2+
kind: PlacementRule
3+
metadata:
4+
name: git-pr
5+
namespace: default
6+
spec:
7+
clusterReplicas: 2
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: apps.open-cluster-management.io/v1
2+
kind: Subscription
3+
metadata:
4+
annotations:
5+
apps.open-cluster-management.io/github-branch: main
6+
apps.open-cluster-management.io/github-path: test/e2e/cases/13-git-res-name/resource
7+
apps.open-cluster-management.io/skip-hub-validation: 'true'
8+
name: git-hub-skip-clone
9+
namespace: default
10+
spec:
11+
channel: default/gitops
12+
placement:
13+
placementRef:
14+
kind: PlacementRule
15+
name: git-pr

test/e2e/cases/23-git-appsub-status-failed/02-channel.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ metadata:
88
apps.open-cluster-management.io/reconcile-rate: high
99
spec:
1010
type: git
11-
pathname: https://github.com/philipwu08/testrepo.git
11+
pathname: 'https://github.com/open-cluster-management-io/multicloud-operators-subscription.git'

test/e2e/cases/23-git-appsub-status-failed/03-subscription.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ metadata:
44
name: guestbook-failed
55
namespace: default
66
annotations:
7-
apps.open-cluster-management.io/github-path: guestbook-failed
7+
apps.open-cluster-management.io/github-path: test/e2e/cases/23-git-appsub-status-failed/resource
88
apps.open-cluster-management.io/github-branch: main
99
spec:
1010
channel: default/git

0 commit comments

Comments
 (0)