Skip to content

Commit 0c218be

Browse files
committed
fix dependencies
1 parent 51e09bc commit 0c218be

File tree

18 files changed

+2443
-12
lines changed

18 files changed

+2443
-12
lines changed

test/extended/ckao.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package extended
2+
3+
import (
4+
"context"
5+
"encoding/base64"
6+
"fmt"
7+
"time"
8+
9+
g "github.com/onsi/ginkgo/v2"
10+
o "github.com/onsi/gomega"
11+
"github.com/openshift/cluster-kube-apiserver-operator/test/extended/util"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/types"
14+
"k8s.io/client-go/kubernetes"
15+
)
16+
17+
var _ = g.Describe("[Jira:kube-apiserver][sig-api-machinery] sanity test", func() {
18+
g.It("should always pass [Suite:openshift/cluster-kube-apiserver-operator/conformance/parallel]", func() {
19+
o.Expect(true).To(o.BeTrue())
20+
})
21+
})
22+
23+
// Helper: scale a Deployment
24+
func scaleDeployment(oc *util.CLI, ns, name string, replicas int32) {
25+
_, err := oc.AdminKubeClient().AppsV1().Deployments(ns).
26+
Patch(context.Background(), name,
27+
types.MergePatchType,
28+
[]byte(fmt.Sprintf(`{"spec":{"replicas":%d}}`, replicas)),
29+
metav1.PatchOptions{})
30+
o.Expect(err).NotTo(o.HaveOccurred())
31+
}
32+
33+
// Helper: patch annotations on a Secret/ConfigMap
34+
func patchAnnotationsOnSecret(oc *util.CLI, ns, name string, anns map[string]*string) {
35+
patch := `{"metadata":{"annotations":{`
36+
first := true
37+
for k, v := range anns {
38+
if !first {
39+
patch += ","
40+
}
41+
if v == nil {
42+
patch += fmt.Sprintf("%q:null", k)
43+
} else {
44+
patch += fmt.Sprintf("%q:%q", k, *v)
45+
}
46+
first = false
47+
}
48+
patch += "}}}"
49+
_, err := oc.AdminKubeClient().CoreV1().Secrets(ns).
50+
Patch(context.Background(), name,
51+
types.MergePatchType, []byte(patch), metav1.PatchOptions{})
52+
o.Expect(err).NotTo(o.HaveOccurred())
53+
}
54+
55+
var _ = g.Describe("[sig-api-machinery][cert-rotation][sidecar-refresh-only-when-expired] merged scenarios", func() {
56+
defer g.GinkgoRecover()
57+
oc := util.NewCLI("cert-rotation", "")
58+
59+
ns := "openshift-kube-apiserver"
60+
secretName := "kubelet-client"
61+
62+
var kc *kubernetes.Clientset
63+
g.BeforeEach(func() {
64+
kc = oc.AdminKubeClient().(*kubernetes.Clientset)
65+
})
66+
67+
g.It("pauses CVO, tests sidecar/operator behavior, then resumes CVO", func() {
68+
ctx := context.Background()
69+
70+
// --- Pause CVO
71+
g.By("Pausing CVO reconciliation")
72+
scaleDeployment(oc, "openshift-cluster-version", "cluster-version-operator", 0)
73+
_, err := oc.AdminConfigClient().ConfigV1().ClusterVersions().
74+
Patch(ctx, "version", types.MergePatchType,
75+
[]byte(`{"spec":{"overrides":[{"kind":"Deployment","group":"apps","namespace":"openshift-cluster-version","name":"cluster-version-operator","unmanaged":true}]}}`),
76+
metav1.PatchOptions{})
77+
o.Expect(err).NotTo(o.HaveOccurred())
78+
79+
defer func() {
80+
// --- Resume CVO
81+
g.By("Resuming CVO reconciliation")
82+
scaleDeployment(oc, "openshift-cluster-version", "cluster-version-operator", 1)
83+
_, _ = oc.AdminConfigClient().ConfigV1().ClusterVersions().
84+
Patch(ctx, "version", types.MergePatchType,
85+
[]byte(`{"spec":{"overrides":[]}}`), metav1.PatchOptions{})
86+
}()
87+
88+
// --- Scenario A
89+
g.By("Scenario A: operator down, removing metadata should not be re-added by sidecar")
90+
scaleDeployment(oc, "openshift-kube-apiserver-operator", "openshift-kube-apiserver-operator", 0)
91+
92+
sec, err := kc.CoreV1().Secrets(ns).Get(ctx, secretName, metav1.GetOptions{})
93+
o.Expect(err).NotTo(o.HaveOccurred())
94+
dataBefore := base64.StdEncoding.EncodeToString(sec.Data["tls.crt"])
95+
96+
patchAnnotationsOnSecret(oc, ns, secretName, map[string]*string{
97+
"auth.openshift.io/component": nil,
98+
"auth.openshift.io/description": nil,
99+
})
100+
101+
o.Consistently(func() bool {
102+
s, _ := kc.CoreV1().Secrets(ns).Get(ctx, secretName, metav1.GetOptions{})
103+
ann := s.Annotations
104+
_, comp := ann["auth.openshift.io/component"]
105+
_, desc := ann["auth.openshift.io/description"]
106+
dataNow := base64.StdEncoding.EncodeToString(s.Data["tls.crt"])
107+
return !comp && !desc && dataNow == dataBefore
108+
}, 2*time.Minute, 10*time.Second).Should(o.BeTrue())
109+
110+
// --- Scenario B
111+
g.By("Scenario B: operator up, metadata restored without cert rotation")
112+
scaleDeployment(oc, "openshift-kube-apiserver-operator", "openshift-kube-apiserver-operator", 1)
113+
114+
o.Eventually(func() bool {
115+
s, _ := kc.CoreV1().Secrets(ns).Get(ctx, secretName, metav1.GetOptions{})
116+
ann := s.Annotations
117+
comp := ann["auth.openshift.io/component"] != ""
118+
desc := ann["auth.openshift.io/description"] != ""
119+
dataNow := base64.StdEncoding.EncodeToString(s.Data["tls.crt"])
120+
return comp && desc && dataNow == dataBefore
121+
}, 3*time.Minute, 10*time.Second).Should(o.BeTrue())
122+
123+
// --- Scenario C
124+
g.By("Scenario C: operator down, expired not-after triggers sidecar rotation")
125+
scaleDeployment(oc, "openshift-kube-apiserver-operator", "openshift-kube-apiserver-operator", 0)
126+
past := "2000-01-01T00:00:00Z"
127+
patchAnnotationsOnSecret(oc, ns, secretName, map[string]*string{
128+
"auth.openshift.io/not-after": &past,
129+
})
130+
131+
o.Eventually(func() bool {
132+
s, _ := kc.CoreV1().Secrets(ns).Get(ctx, secretName, metav1.GetOptions{})
133+
dataNow := base64.StdEncoding.EncodeToString(s.Data["tls.crt"])
134+
ann := s.Annotations
135+
na := ann["auth.openshift.io/not-after"]
136+
if na == "" {
137+
return false
138+
}
139+
// content rotated
140+
return dataNow != dataBefore
141+
}, 3*time.Minute, 10*time.Second).Should(o.BeTrue())
142+
143+
// scale operator back up for cleanup
144+
scaleDeployment(oc, "openshift-kube-apiserver-operator", "openshift-kube-apiserver-operator", 1)
145+
})
146+
})

test/extended/main.go

Lines changed: 0 additions & 12 deletions
This file was deleted.

test/extended/util/assert.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package util
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"strings"
8+
9+
g "github.com/onsi/ginkgo/v2"
10+
o "github.com/onsi/gomega"
11+
)
12+
13+
// e is return value of Wait.Poll
14+
// msg is the reason why time out
15+
// the function assert return value of Wait.Poll, and expect NO error
16+
// if e is Nil, just pass and nothing happen.
17+
// if e is not Nil, will not print the default error message "timed out waiting for the condition" because it causes RP AA not to analysis result exactly.
18+
// if e is "timed out waiting for the condition" or "context deadline exceeded", it is replaced by msg.
19+
// if e is not "timed out waiting for the condition", it print e and then case fails.
20+
21+
func AssertWaitPollNoErr(e error, msg string) {
22+
if e == nil {
23+
return
24+
}
25+
var err error
26+
if errors.Is(e, context.DeadlineExceeded) ||
27+
strings.Compare(e.Error(), "timed out waiting for the condition") == 0 ||
28+
strings.Compare(e.Error(), "context deadline exceeded") == 0 {
29+
err = fmt.Errorf("case: %v\nerror: %s", g.CurrentSpecReport().FullText(), msg)
30+
} else {
31+
err = fmt.Errorf("case: %v\nerror: %s", g.CurrentSpecReport().FullText(), e.Error())
32+
}
33+
o.Expect(err).NotTo(o.HaveOccurred())
34+
}
35+
36+
// OrFail function will process another function's return values and fail if any of those returned values is ane error != nil and returns the first value
37+
// example: if we have: func getValued() (string, error)
38+
//
39+
// we can do: value := OrFail[string](getValue())
40+
func OrFail[T any](vals ...any) T {
41+
42+
for _, val := range vals {
43+
err, ok := val.(error)
44+
if ok {
45+
o.ExpectWithOffset(1, err).NotTo(o.HaveOccurred())
46+
}
47+
}
48+
49+
return vals[0].(T)
50+
}

0 commit comments

Comments
 (0)