diff --git a/pkg/splunk/controller/messages.go b/pkg/splunk/controller/messages.go new file mode 100644 index 000000000..7ffe1a86e --- /dev/null +++ b/pkg/splunk/controller/messages.go @@ -0,0 +1,19 @@ +// Copyright (c) 2018-2020 Splunk Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controller + +const ( + invalidSecretObjectError = "Invalid secret object" +) diff --git a/pkg/splunk/controller/secret.go b/pkg/splunk/controller/secret.go index 9deb83d42..30868a246 100644 --- a/pkg/splunk/controller/secret.go +++ b/pkg/splunk/controller/secret.go @@ -16,6 +16,8 @@ package controller import ( "context" + "errors" + "reflect" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -25,22 +27,36 @@ import ( // ApplySecret creates or updates a Kubernetes Secret, and returns active secrets if successful func ApplySecret(client splcommon.ControllerClient, secret *corev1.Secret) (*corev1.Secret, error) { + // Invalid secret object + if secret == nil { + return nil, errors.New(invalidSecretObjectError) + } + scopedLog := log.WithName("ApplySecret").WithValues( "name", secret.GetObjectMeta().GetName(), "namespace", secret.GetObjectMeta().GetNamespace()) - namespacedName := types.NamespacedName{Namespace: secret.GetNamespace(), Name: secret.GetName()} - var current corev1.Secret - result := ¤t + var result corev1.Secret - err := client.Get(context.TODO(), namespacedName, ¤t) + namespacedName := types.NamespacedName{Namespace: secret.GetNamespace(), Name: secret.GetName()} + err := client.Get(context.TODO(), namespacedName, &result) if err == nil { - // found existing Secret: do nothing - scopedLog.Info("Found existing Secret") + scopedLog.Info("Found existing Secret, update if needed") + if !reflect.DeepEqual(&result, secret) { + result = *secret + err = UpdateResource(client, &result) + if err != nil { + return nil, err + } + } } else { + scopedLog.Info("Didn't find secret, creating one") err = CreateResource(client, secret) - result = secret + if err != nil { + return nil, err + } + result = *secret } - return result, err + return &result, nil } diff --git a/pkg/splunk/controller/secret_test.go b/pkg/splunk/controller/secret_test.go index 7dcca7c83..0470a7463 100644 --- a/pkg/splunk/controller/secret_test.go +++ b/pkg/splunk/controller/secret_test.go @@ -15,6 +15,7 @@ package controller import ( + "reflect" "testing" corev1 "k8s.io/api/core/v1" @@ -24,9 +25,10 @@ import ( ) func TestApplySecret(t *testing.T) { + // Re-concile tester funcCalls := []spltest.MockFuncCall{{MetaName: "*v1.Secret-test-secrets"}} createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": funcCalls} - updateCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls} + updateCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Update": funcCalls} current := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "secrets", @@ -40,4 +42,35 @@ func TestApplySecret(t *testing.T) { return err } spltest.ReconcileTester(t, "TestApplySecret", ¤t, revised, createCalls, updateCalls, reconcile, false) + + // Test create and update scenarios + c := spltest.NewMockClient() + + // Test create + current.Data = map[string][]byte{"a": {'1', '1'}} + retr, err := ApplySecret(c, ¤t) + if err != nil { + t.Errorf("ApplySecret failed %s", err.Error()) + } + + if !reflect.DeepEqual(retr, ¤t) { + t.Errorf("Incorrect create got %+v want %+v", retr, current) + } + + // Test Update + retr.Data = map[string][]byte{"a": {'1', '2'}} + retr2, err := ApplySecret(c, retr) + if err != nil { + t.Errorf("ApplySecret failed %s", err.Error()) + } + + if !reflect.DeepEqual(retr, retr2) { + t.Errorf("Incorrect update got %+v want %+v", retr2, retr) + } + + // Negative testing + _, err = ApplySecret(c, nil) + if err.Error() != invalidSecretObjectError { + t.Errorf("Didn't catch invalid secret object") + } } diff --git a/pkg/splunk/enterprise/messages.go b/pkg/splunk/enterprise/messages.go index 0dc036e91..f482e2be2 100644 --- a/pkg/splunk/enterprise/messages.go +++ b/pkg/splunk/enterprise/messages.go @@ -1,3 +1,17 @@ +// Copyright (c) 2018-2020 Splunk Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package enterprise const (