1 package encryptionctl_test
2
3 import (
4 "context"
5 "os"
6 "testing"
7 "time"
8
9 corev1 "k8s.io/api/core/v1"
10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11 "k8s.io/apimachinery/pkg/types"
12 ctrl "sigs.k8s.io/controller-runtime"
13
14 "github.com/stretchr/testify/suite"
15 "k8s.io/apimachinery/pkg/runtime"
16 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
17
18 api "edge-infra.dev/pkg/edge/iam/api/v1alpha1"
19 "edge-infra.dev/pkg/lib/fog"
20
21 "edge-infra.dev/pkg/edge/iam/ctl/encryptionctl"
22 "edge-infra.dev/pkg/edge/iam/ctl/providerctl"
23 "edge-infra.dev/pkg/k8s/runtime/controller"
24 "edge-infra.dev/test"
25 "edge-infra.dev/test/framework"
26 "edge-infra.dev/test/framework/k8s"
27 "edge-infra.dev/test/framework/k8s/envtest"
28 )
29
30
31
32
33
34
35
36
37
38 type Suite struct {
39 *framework.Framework
40 *k8s.K8s
41 ctx context.Context
42 timeout time.Duration
43 tick time.Duration
44 }
45
46 func TestEncryptionReconcilerSetup(t *testing.T) {
47
48 os.Setenv("IAM_CLUSTER_ID", "123")
49 os.Setenv("IAM_ENCRYPTION_ENABLED", "true")
50
51
52 testEnv := envtest.Setup()
53 cfg, opts := controller.ProcessOptions(controller.WithCfg(testEnv.Config), controller.WithMetricsAddress("0"))
54 opts.Scheme = createScheme()
55 ctrl.SetLogger(fog.New())
56 mgr, err := ctrl.NewManager(cfg, opts)
57 if err != nil {
58 t.Errorf("unable to create manager: %v", err)
59 }
60
61 f := framework.New("providerctl").Component("providerctl")
62 s := &Suite{
63 Framework: f,
64 ctx: context.Background(),
65 timeout: 10 * time.Second,
66 tick: 50 * time.Millisecond,
67 }
68
69 providerRec := &providerctl.ProviderReconciler{
70 Name: "provider-controller",
71 Client: mgr.GetClient(),
72 Scheme: mgr.GetScheme(),
73 }
74 err = providerRec.SetupWithManager(mgr)
75 test.NoError(err)
76
77
78 encryptionRec := &encryptionctl.EncryptionSecretReconciler{
79 Name: "encryption-secret-controller",
80 Client: mgr.GetClient(),
81 }
82 err = encryptionRec.SetupWithManager(mgr)
83 test.NoError(err)
84
85 k := k8s.New(testEnv.Config, k8s.WithCtrlManager(mgr), k8s.WithKonfigKonnector())
86 s.K8s = k
87
88 f.Register(k)
89
90 suite.Run(t, s)
91
92 t.Cleanup(func() {
93 f.NoError(testEnv.Stop())
94 })
95 }
96
97 func (s *Suite) TestEncryptionSecretReconciler() {
98
99 namespace := &corev1.Namespace{
100 TypeMeta: metav1.TypeMeta{
101 Kind: "Namespace",
102 APIVersion: "v1",
103 },
104 ObjectMeta: metav1.ObjectMeta{
105 Name: "edge-iam",
106 },
107 }
108 s.Require().NoError(s.Client.Create(s.ctx, namespace))
109
110
111 secret := &corev1.Secret{}
112 secret.ObjectMeta = metav1.ObjectMeta{
113 Name: "private-key-secret",
114 Namespace: "edge-iam",
115 }
116 secret.Data = map[string][]byte{
117 "private_key": []byte("key"),
118 "private_key_id": []byte("key-id"),
119 }
120 s.Require().NoError(s.Client.Create(s.ctx, secret))
121
122
123 challengeSecret := &corev1.Secret{}
124 challengeSecret.ObjectMeta = metav1.ObjectMeta{
125 Name: "challenge-secret",
126 Namespace: "edge-iam",
127 }
128 challengeSecret.Data = map[string][]byte{
129 "secret": []byte("secret"),
130 }
131 s.Require().NoError(s.Client.Create(s.ctx, challengeSecret))
132
133
134 provider := createProviderObj("1", "1")
135 s.Require().NoError(s.Client.Create(s.ctx, provider))
136
137
138 encryptionSecret := getSecret()
139 s.Require().NoError(s.Client.Create(s.ctx, encryptionSecret.DeepCopy()))
140
141
142 providerObj := &api.Provider{}
143 s.Require().Eventually(func() bool {
144 err := s.Client.Get(s.ctx, types.NamespacedName{
145 Name: "provider",
146 Namespace: "edge-iam",
147 }, providerObj)
148 return err == nil
149 }, s.timeout, s.tick, "expected provider object was never found")
150
151
152 for _, status := range providerObj.Status.Conditions {
153 if status.Reason == "EncryptionRotationSucceeded" {
154 s.Require().Equal(status.Message, "successfully updated databases to version: 1")
155 }
156 }
157 }
158
159 func getSecret() corev1.Secret {
160 secret := corev1.Secret{
161 TypeMeta: metav1.TypeMeta{
162 Kind: "Secret",
163 APIVersion: "v1",
164 },
165 ObjectMeta: metav1.ObjectMeta{
166 Name: "id-encryption-key-1",
167 Namespace: "edge-iam",
168 },
169 Data: map[string][]byte{
170 "key": []byte("my-32bit-super-extra-secret-key!"),
171 },
172 }
173 return secret
174 }
175
176 func createProviderObj(specVersion string, statusVersion string) *api.Provider {
177 statusMessage := "successfully updated databases to version: " + statusVersion
178 providerObj := &api.Provider{
179 TypeMeta: metav1.TypeMeta{
180 APIVersion: "iam.edge-infra.dev/v1alpha1",
181 Kind: "Provider",
182 },
183 ObjectMeta: metav1.ObjectMeta{
184 Name: "provider",
185 Namespace: "edge-iam",
186 },
187 Spec: api.ProviderSpec{
188 Encryption: api.EncryptionFields{
189 Version: specVersion,
190 },
191 Issuer: "http://localhost:8080",
192 Target: "kind",
193 },
194 Status: api.ProviderStatus{
195 Conditions: []metav1.Condition{
196 {
197 Type: "DatabaseUpdated",
198 Status: metav1.ConditionTrue,
199 Reason: "EncryptionRotationSucceeded",
200 Message: statusMessage,
201 },
202 },
203 },
204 }
205 return providerObj
206 }
207
208 func createScheme() *runtime.Scheme {
209 scheme := runtime.NewScheme()
210 utilruntime.Must(api.AddToScheme(scheme))
211 utilruntime.Must(corev1.AddToScheme(scheme))
212 return scheme
213 }
214
View as plain text