From de882bc4f8c5843f2a4bae9f961153e1d451853b Mon Sep 17 00:00:00 2001 From: Grzegorz Grasza Date: Thu, 17 Oct 2024 09:14:19 +0000 Subject: [PATCH] Generate and rotate keys After configuration change, keys need to be added/removed and rotated in the proper order to ensure that the sessions don't expire prematurely. --- controllers/keystoneapi_controller.go | 122 ++++++++++++++++++++------ 1 file changed, 95 insertions(+), 27 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index 8f53444a..067bf684 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1382,42 +1382,110 @@ func (r *KeystoneAPIReconciler) ensureFernetKeys( if err != nil && !k8s_errors.IsNotFound(err) { return err + } else if k8s_errors.IsNotFound(err) { + fernetKeys := map[string]string{ + "CredentialKeys0": keystone.GenerateFernetKey(), + "CredentialKeys1": keystone.GenerateFernetKey(), + } + var numberKeys int + fmt.Sscan(instance.Spec.FernetMaxActiveKeys, &numberKeys) + for i := 0; i < numberKeys; i++ { + fernetKeys[fmt.Sprintf("FernetKeys%d", i)] = keystone.GenerateFernetKey() + } + + tmpl := []util.Template{ + { + Name: secretName, + Namespace: instance.Namespace, + Type: util.TemplateTypeNone, + CustomData: fernetKeys, + Labels: labels, + }, + } + err := oko_secret.EnsureSecrets(ctx, helper, instance, tmpl, envVars) + if err != nil { + return err + } } else { // add hash to envVars (*envVars)[secret.Name] = env.SetValue(hash) - } - fernetKeys := map[string]string{ - "CredentialKeys0": keystone.GenerateFernetKey(), - "CredentialKeys1": keystone.GenerateFernetKey(), - } + var numberKeys int + fmt.Sscan(instance.Spec.FernetMaxActiveKeys, &numberKeys) - var numberKeys int - fmt.Sscan(instance.Spec.FernetMaxActiveKeys, &numberKeys) + changed_keys := false - for i := 0; i < numberKeys; i++ { - key := fmt.Sprintf("FernetKeys%d", i) - v, exists := secret.Data[key] - if exists { - fernetKeys[key] = string(v[:]) - } else { - fernetKeys[key] = keystone.GenerateFernetKey() + // + // Remove extra keys when FernetMaxActiveKeys changes + // + extra_key := fmt.Sprintf("FernetKeys%d", numberKeys) + for { + _, exists := secret.Data[extra_key] + if !exists { + break + } + changed_keys = true + i := 1 + for { + key := fmt.Sprintf("FernetKeys%d", i) + i += 1 + next_key := fmt.Sprintf("FernetKeys%d", i) + _, exists = secret.Data[next_key] + if !exists { + break + } + secret.Data[key] = secret.Data[next_key] + delete(secret.Data, next_key) + } } - } - tmpl := []util.Template{ - { - Name: secretName, - Namespace: instance.Namespace, - Type: util.TemplateTypeNone, - CustomData: fernetKeys, - Labels: labels, - }, - } + // + // Add extra keys when FernetMaxActiveKeys changes + // + last_key := fmt.Sprintf("FernetKeys%d", numberKeys-1) + for { + _, exists := secret.Data[last_key] + if exists { + break + } + changed_keys = true + i := 1 + next_key_value := []byte(keystone.GenerateFernetKey()) + for { + key := fmt.Sprintf("FernetKeys%d", i) + i += 1 + key_value, exists := secret.Data[key] + secret.Data[key] = next_key_value + next_key_value = key_value + if !exists { + break + } + } + } - err = oko_secret.EnsureSecrets(ctx, helper, instance, tmpl, envVars) - if err != nil { - return err + if !changed_keys { + return nil + } + + fernetKeys := make(map[string]string, len(secret.Data)) + for k, v := range secret.Data { + fernetKeys[k] = string(v[:]) + } + + tmpl := []util.Template{ + { + Name: secretName, + Namespace: instance.Namespace, + Type: util.TemplateTypeNone, + CustomData: fernetKeys, + Labels: labels, + }, + } + + err = oko_secret.EnsureSecrets(ctx, helper, instance, tmpl, envVars) + if err != nil { + return err + } } return nil