diff --git a/tests/service_opts_test.go b/tests/service_opts_test.go index 23fdc028b..5b37789c2 100644 --- a/tests/service_opts_test.go +++ b/tests/service_opts_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "k8s.io/utils/pointer" "github.com/aiven/aiven-operator/api/v1alpha1" ) @@ -80,3 +81,114 @@ func TestServiceTechnicalEmails(t *testing.T) { require.NoError(t, err) assert.Empty(t, grafanaAvnUpdated.TechnicalEmails) } + +func getConnInfoSecretTargetDisabledYaml(project, name, cloudName string, connInfoSecretTargetDisabled *bool) string { + baseYaml := ` +apiVersion: aiven.io/v1alpha1 +kind: Grafana +metadata: + name: %[2]s +spec: + authSecretRef: + name: aiven-token + key: token + + project: %[1]s + cloudName: %[3]s + plan: startup-1 +` + if connInfoSecretTargetDisabled != nil { + baseYaml += fmt.Sprintf(` + connInfoSecretTargetDisabled: %t +`, *connInfoSecretTargetDisabled) + } + + return fmt.Sprintf(baseYaml, project, name, cloudName) +} + +func runTest(t *testing.T, scenario TestScenario) { + defer recoverPanic(t) + + // GIVEN + name := randName("grafana") + yml := getConnInfoSecretTargetDisabledYaml(testProject, name, testPrimaryCloudName, scenario.initialConnInfoSecretTargetDisabled) + s := NewSession(k8sClient, avnClient, testProject) + + // Cleans test afterwards + defer s.Destroy() + + // WHEN + // Applies given manifest + require.NoError(t, s.Apply(yml)) + + // Waits kube objects + grafana := new(v1alpha1.Grafana) + require.NoError(t, s.GetRunning(grafana, name)) + + // THEN + // Check if service connection info secret is created + secret, err := s.GetSecret(grafana.GetName()) + if scenario.shouldSecretBeCreated { + assert.NoError(t, err) + assert.NotEmpty(t, secret) + } else { + assert.Nil(t, secret) + } + + // WHEN + // Trying to update service an existing service with updated `connInfoSecretTargetDisabled` + updatedYml := getConnInfoSecretTargetDisabledYaml(testProject, name, testPrimaryCloudName, scenario.updatedConnInfoSecretTargetDisabled) + + // Applies updated manifest + err = s.Apply(updatedYml) + expectedErrorMsg := fmt.Sprintf(scenario.expectedErrorMsg, name) + assert.EqualErrorf(t, err, expectedErrorMsg, "Error should be: %v, got: %v", expectedErrorMsg, err) +} + +type TestScenario struct { + name string + initialConnInfoSecretTargetDisabled *bool + updatedConnInfoSecretTargetDisabled *bool + shouldSecretBeCreated bool + expectedErrorMsg string +} + +func TestServiceConnInfoSecretTargetDisabled(t *testing.T) { + cases := []TestScenario{ + { + // Modifying `connInfoSecretTargetDisabled` from missing to true --> A secret is created, but the update fails + // because `connInfoSecretTargetDisabled` can only be set during service creation. + name: "modify from missing to true", + initialConnInfoSecretTargetDisabled: nil, + updatedConnInfoSecretTargetDisabled: pointer.Bool(true), + shouldSecretBeCreated: true, + expectedErrorMsg: `Grafana.aiven.io "%s" is invalid: spec: Invalid value: "object": connInfoSecretTargetDisabled can only be set during service creation.`, + }, + { + // Modifying `connInfoSecretTargetDisabled` from true to missing --> A secret is not created and the update fails + // because `connInfoSecretTargetDisabled` can only be set during service creation. + name: "modify from true to missing", + initialConnInfoSecretTargetDisabled: pointer.Bool(true), + updatedConnInfoSecretTargetDisabled: nil, + shouldSecretBeCreated: false, + expectedErrorMsg: `Grafana.aiven.io "%s" is invalid: spec: Invalid value: "object": connInfoSecretTargetDisabled can only be set during service creation.`, + }, + { + // Modifying `connInfoSecretTargetDisabled` from true to false --> A secret is not created and the update fails + // due to the immutability of `connInfoSecretTargetDisabled`. + name: "modify from true to false", + initialConnInfoSecretTargetDisabled: pointer.Bool(true), + updatedConnInfoSecretTargetDisabled: pointer.Bool(false), + shouldSecretBeCreated: false, + expectedErrorMsg: `Grafana.aiven.io "%s" is invalid: spec.connInfoSecretTargetDisabled: Invalid value: "boolean": connInfoSecretTargetDisabled is immutable.`, + }, + } + + for _, opt := range cases { + opt := opt + t.Run(opt.name, func(t *testing.T) { + t.Parallel() + runTest(t, opt) + }) + } +}