@@ -219,6 +219,176 @@ func TestAreSecretHashesInSync(t *testing.T) {
219219 }
220220}
221221
222+ func TestIsSecretHashInSync_CRDNotInstalled (t * testing.T ) {
223+ s := runtime .NewScheme ()
224+ _ = corev1 .AddToScheme (s )
225+ mapper := meta .NewDefaultRESTMapper ([]schema.GroupVersion {})
226+
227+ c := fake .NewClientBuilder ().
228+ WithScheme (s ).
229+ WithRESTMapper (mapper ).
230+ Build ()
231+
232+ inSync , info , err := IsSecretHashInSync (context .Background (), c , "test" , "any-secret" )
233+ if err != nil {
234+ t .Errorf ("IsSecretHashInSync() unexpected error: %v" , err )
235+ }
236+ if ! inSync {
237+ t .Errorf ("IsSecretHashInSync() inSync = false, want true when CRD not installed (info: %s)" , info )
238+ }
239+ }
240+
241+ func TestIsSecretHashInSync (t * testing.T ) {
242+ hmacSecret := & corev1.Secret {
243+ ObjectMeta : metav1.ObjectMeta {
244+ Name : "instanceha-0-heartbeat-hmac" ,
245+ Namespace : "test" ,
246+ },
247+ Data : map [string ][]byte {"hmac-key" : []byte ("current-key" )},
248+ }
249+ hmacHash , _ := oko_secret .Hash (hmacSecret )
250+
251+ otherSecret := & corev1.Secret {
252+ ObjectMeta : metav1.ObjectMeta {
253+ Name : "nova-cell1-compute-config" ,
254+ Namespace : "test" ,
255+ },
256+ Data : map [string ][]byte {"config" : []byte ("nova-config" )},
257+ }
258+
259+ tests := []struct {
260+ name string
261+ secretName string
262+ nodesets []* k8s_unstructured.Unstructured
263+ secrets []* corev1.Secret
264+ wantInSync bool
265+ wantInfoSubstr string
266+ }{
267+ {
268+ name : "no nodesets exist" ,
269+ secretName : "instanceha-0-heartbeat-hmac" ,
270+ wantInSync : true ,
271+ },
272+ {
273+ name : "secret not tracked by any nodeset" ,
274+ secretName : "instanceha-0-heartbeat-hmac" ,
275+ nodesets : []* k8s_unstructured.Unstructured {
276+ makeNodeSet ("ns1" , "test" , map [string ]string {
277+ "nova-cell1-compute-config" : "some-hash" ,
278+ }),
279+ },
280+ secrets : []* corev1.Secret {hmacSecret , otherSecret },
281+ wantInSync : true ,
282+ },
283+ {
284+ name : "secret in sync" ,
285+ secretName : "instanceha-0-heartbeat-hmac" ,
286+ nodesets : []* k8s_unstructured.Unstructured {
287+ makeNodeSet ("ns1" , "test" , map [string ]string {
288+ "instanceha-0-heartbeat-hmac" : hmacHash ,
289+ "nova-cell1-compute-config" : "stale-hash" ,
290+ }),
291+ },
292+ secrets : []* corev1.Secret {hmacSecret , otherSecret },
293+ wantInSync : true ,
294+ },
295+ {
296+ name : "secret out of sync" ,
297+ secretName : "instanceha-0-heartbeat-hmac" ,
298+ nodesets : []* k8s_unstructured.Unstructured {
299+ makeNodeSet ("ns1" , "test" , map [string ]string {
300+ "instanceha-0-heartbeat-hmac" : "old-hash" ,
301+ }),
302+ },
303+ secrets : []* corev1.Secret {hmacSecret },
304+ wantInSync : false ,
305+ wantInfoSubstr : "has changed since last deployment" ,
306+ },
307+ {
308+ name : "secret deleted" ,
309+ secretName : "instanceha-0-heartbeat-hmac" ,
310+ nodesets : []* k8s_unstructured.Unstructured {
311+ makeNodeSet ("ns1" , "test" , map [string ]string {
312+ "instanceha-0-heartbeat-hmac" : "some-hash" ,
313+ }),
314+ },
315+ secrets : []* corev1.Secret {},
316+ wantInSync : false ,
317+ wantInfoSubstr : "no longer exists" ,
318+ },
319+ {
320+ name : "multiple nodesets - one stale for this secret" ,
321+ secretName : "instanceha-0-heartbeat-hmac" ,
322+ nodesets : []* k8s_unstructured.Unstructured {
323+ makeNodeSet ("up-to-date" , "test" , map [string ]string {
324+ "instanceha-0-heartbeat-hmac" : hmacHash ,
325+ }),
326+ makeNodeSet ("stale" , "test" , map [string ]string {
327+ "instanceha-0-heartbeat-hmac" : "old-hash" ,
328+ }),
329+ },
330+ secrets : []* corev1.Secret {hmacSecret },
331+ wantInSync : false ,
332+ wantInfoSubstr : "has changed since last deployment" ,
333+ },
334+ {
335+ name : "other secret stale does not affect this secret" ,
336+ secretName : "instanceha-0-heartbeat-hmac" ,
337+ nodesets : []* k8s_unstructured.Unstructured {
338+ makeNodeSet ("ns1" , "test" , map [string ]string {
339+ "instanceha-0-heartbeat-hmac" : hmacHash ,
340+ "unrelated-secret" : "stale-hash" ,
341+ }),
342+ },
343+ secrets : []* corev1.Secret {hmacSecret },
344+ wantInSync : true ,
345+ },
346+ }
347+
348+ for _ , tt := range tests {
349+ t .Run (tt .name , func (t * testing.T ) {
350+ s , mapper := newTestSchemeAndMapper ()
351+
352+ builder := fake .NewClientBuilder ().
353+ WithScheme (s ).
354+ WithRESTMapper (mapper )
355+
356+ for _ , ns := range tt .nodesets {
357+ builder = builder .WithObjects (ns )
358+ }
359+ for _ , sec := range tt .secrets {
360+ builder = builder .WithObjects (sec )
361+ }
362+
363+ c := builder .Build ()
364+
365+ inSync , info , err := IsSecretHashInSync (
366+ context .Background (),
367+ c ,
368+ "test" ,
369+ tt .secretName ,
370+ )
371+
372+ if err != nil {
373+ t .Errorf ("IsSecretHashInSync() unexpected error: %v" , err )
374+ return
375+ }
376+
377+ if inSync != tt .wantInSync {
378+ t .Errorf ("IsSecretHashInSync() inSync = %v, want %v (info: %s)" , inSync , tt .wantInSync , info )
379+ }
380+
381+ if tt .wantInfoSubstr != "" {
382+ if info == "" {
383+ t .Errorf ("IsSecretHashInSync() info is empty, want substring %q" , tt .wantInfoSubstr )
384+ } else if ! strings .Contains (info , tt .wantInfoSubstr ) {
385+ t .Errorf ("IsSecretHashInSync() info = %q, want substring %q" , info , tt .wantInfoSubstr )
386+ }
387+ }
388+ })
389+ }
390+ }
391+
222392func TestHaveNodeSets_CRDNotInstalled (t * testing.T ) {
223393 s := runtime .NewScheme ()
224394 _ = corev1 .AddToScheme (s )
0 commit comments