diff --git a/pkg/controller/stack/stack_controller.go b/pkg/controller/stack/stack_controller.go index c2f26bba..2de94803 100644 --- a/pkg/controller/stack/stack_controller.go +++ b/pkg/controller/stack/stack_controller.go @@ -1640,7 +1640,6 @@ func (sess *reconcileStackSession) SetupGitAuth(ctx context.Context) (*auto.GitA if sess.stack.GitAuth != nil { if sess.stack.GitAuth.SSHAuth != nil { - fmt.Println("sess.stack.GitAuth/SSHAuth: ", sess.stack.GitAuth.SSHAuth) privateKey, err := sess.resolveResourceRef(ctx, &sess.stack.GitAuth.SSHAuth.SSHPrivateKey) if err != nil { return nil, fmt.Errorf("resolving gitAuth SSH private key: %w", err) diff --git a/test/program_test.go b/test/program_test.go index 8b3564e9..2b6b6164 100644 --- a/test/program_test.go +++ b/test/program_test.go @@ -13,12 +13,70 @@ import ( pulumiv1 "github.com/pulumi/pulumi-kubernetes-operator/pkg/apis/pulumi/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - yaml "sigs.k8s.io/yaml" + "sigs.k8s.io/yaml" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) +// pulumiYamlProgramCMFmt is a template for a YAML program that creates a ConfigMap. Templated +// values are: the name of the ConfigMap, and the value of the `foo` key in the ConfigMap's `data` +const pulumiYamlProgramCMFmt = ` +configuration: + foo: + type: "String" + default: "%s" +resources: + provider: + type: pulumi:providers:kubernetes + options: + version: 3.26.0 + example: + type: kubernetes:core/v1:ConfigMap + properties: + metadata: + annotations: + pulumi.com/patchForce: "true" + name: + %s + data: + foo: ${foo} + options: + provider: ${provider} +` + +// invalidPulumiYamlProgramCM is a YAML program that creates a ConfigMap, but with an invalid Pulumi YAML format. +const invalidPulumiYamlProgramCM = ` +resources: + example: + type: kubernetes:core/v1:ConfigMap + properties: + metadata: + annotations: + pulumi.com/patchForce: "true" + name: + %s + data: + foo: bar + options: + provider: ${provider} +` + +// generatePulumiYamlCMProgram generates a Pulumi YAML program that creates a ConfigMap. It accepts a base +// template and values to be templated into the base template. +func generatePulumiYamlCMProgram(template string, values ...interface{}) pulumiv1.Program { + prog := pulumiv1.Program{} + prog.Name = randString() + prog.Namespace = "default" + + templated := fmt.Sprintf(template, values...) + + err := yaml.Unmarshal([]byte(templated), &prog.Program) + ExpectWithOffset(1, err).ToNot(HaveOccurred()) + + return prog +} + var _ = Describe("Creating a YAML program", func() { It("is possible to create an empty YAML program", func() { prog := pulumiv1.Program{} @@ -63,6 +121,7 @@ var _ = Describe("Creating a YAML program", func() { Expect(k8sClient.Create(context.TODO(), &stack)).To(Succeed()) deleteAndWaitForFinalization(&stack) + deleteAndWaitForFinalization(&prog) }) When("Using a stack", func() { @@ -116,7 +175,7 @@ var _ = Describe("Creating a YAML program", func() { }) It("should fail if given a syntactically correct but invalid program.", func() { - prog := programFromFile("./testdata/test-program-invalid.yaml") + prog := generatePulumiYamlCMProgram(invalidPulumiYamlProgramCM, "cm-"+randString()) Expect(k8sClient.Create(context.TODO(), &prog)).To(Succeed()) stack.Spec.ProgramRef = &shared.ProgramReference{ @@ -130,38 +189,37 @@ var _ = Describe("Creating a YAML program", func() { }) It("should run a Program that has been added to a Stack", func() { - prog := programFromFile("./testdata/test-program.yaml") + cmName := "cm-" + randString() + prog := generatePulumiYamlCMProgram(pulumiYamlProgramCMFmt, "bar", cmName) Expect(k8sClient.Create(context.TODO(), &prog)).To(Succeed()) stack.Spec.ProgramRef = &shared.ProgramReference{ Name: prog.Name, } - // Set DestroyOnFinalize to clean up the configmap for repeat runs. - stack.Spec.DestroyOnFinalize = true stack.Name = "ok-program-" + randString() Expect(k8sClient.Create(context.TODO(), &stack)).To(Succeed()) waitForStackSuccess(&stack) expectReady(stack.Status.Conditions) + // Check that the ConfigMap was created. var c corev1.ConfigMap - Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: stack.Namespace, Name: "test-configmap"}, &c)).To(Succeed()) + Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: stack.Namespace, Name: cmName}, &c)).To(Succeed()) }) When("the program is changed", func() { var revisionOnFirstSuccess string BeforeEach(func() { - prog := programFromFile("./testdata/test-program.yaml") + cmName := "changing-cm-" + randString() + prog := generatePulumiYamlCMProgram(pulumiYamlProgramCMFmt, "bar", cmName) Expect(k8sClient.Create(context.TODO(), &prog)).To(Succeed()) stack.Spec.ProgramRef = &shared.ProgramReference{ Name: prog.Name, } - // Set DestroyOnFinalize to clean up the configmap for repeat runs. - stack.Spec.DestroyOnFinalize = true stack.Name = "changing-program-" + randString() Expect(k8sClient.Create(context.TODO(), &stack)).To(Succeed()) waitForStackSuccess(&stack) @@ -169,7 +227,7 @@ var _ = Describe("Creating a YAML program", func() { Expect(stack.Status.LastUpdate).ToNot(BeNil()) revisionOnFirstSuccess = stack.Status.LastUpdate.LastSuccessfulCommit fmt.Fprintf(GinkgoWriter, ".status.lastUpdate.LastSuccessfulCommit before changing program: %s", revisionOnFirstSuccess) - prog2 := programFromFile("./testdata/test-program-changed.yaml") + prog2 := generatePulumiYamlCMProgram(pulumiYamlProgramCMFmt, "newValue", cmName) prog.Program = prog2.Program resetWaitForStack() Expect(k8sClient.Update(context.TODO(), &prog)).To(Succeed()) @@ -184,19 +242,3 @@ var _ = Describe("Creating a YAML program", func() { }) }) }) - -func programFromFile(path string) pulumiv1.Program { - prog := pulumiv1.Program{} - prog.Name = randString() - prog.Namespace = "default" - - programFile, err := os.ReadFile(path) - if err != nil { - fmt.Printf("%+v", err) - Fail(fmt.Sprintf("couldn't read program file: %v", err)) - } - err = yaml.Unmarshal(programFile, &prog.Program) - ExpectWithOffset(1, err).ToNot(HaveOccurred()) - - return prog -} diff --git a/test/stack_controller_test.go b/test/stack_controller_test.go index e64613a3..f0645990 100644 --- a/test/stack_controller_test.go +++ b/test/stack_controller_test.go @@ -36,7 +36,6 @@ var ( baseDir = "" ) -const namespace = "default" const pulumiAPISecretName = "pulumi-api-secret" const pulumiAWSSecretName = "pulumi-aws-secrets" const k8sOpTimeout = 10 * time.Second diff --git a/test/stale_state_test.go b/test/stale_state_test.go index 61b4caca..f6a797c0 100644 --- a/test/stale_state_test.go +++ b/test/stale_state_test.go @@ -9,7 +9,6 @@ import ( "math/rand" "os" "path/filepath" - "strings" "time" "github.com/pulumi/pulumi-kubernetes-operator/pkg/apis/pulumi/shared" @@ -20,7 +19,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = When("a stack uses a provider with credentials kept in state", func() { +var _ = When("a stack uses a provider with credentials kept in state", Ordered, func() { // This models a situation in which the program constructs a provider using credentials which // are then rotated. Pulumi has difficulty with this if you want to refresh the state, since the // provider will be constructed from the credentials in the state, which are out of date. The @@ -122,9 +121,7 @@ var _ = When("a stack uses a provider with credentials kept in state", func() { AfterEach(func() { deleteAndWaitForFinalization(useRabbitStack) deleteAndWaitForFinalization(setupStack) - if strings.HasPrefix(tmp, os.TempDir()) { - Expect(os.RemoveAll(tmp)).To(Succeed()) - } + os.RemoveAll(tmp) }) When("the credentials are rotated", func() { @@ -140,7 +137,7 @@ var _ = When("a stack uses a provider with credentials kept in state", func() { "port": rabbitPort, "secretName": credsSecretName, } - waitForStackSince = time.Now() + resetWaitForStack() Expect(k8sClient.Update(ctx, setupStack)).To(Succeed()) waitForStackSuccess(setupStack, "120s") }) @@ -209,7 +206,7 @@ var _ = When("a stack uses a provider with credentials kept in state", func() { "port": rabbitPort, "secretName": credsSecretName, } - waitForStackSince = time.Now() + resetWaitForStack() Expect(k8sClient.Update(ctx, setupStack)).To(Succeed()) waitForStackSuccess(setupStack, "120s") }) @@ -217,7 +214,7 @@ var _ = When("a stack uses a provider with credentials kept in state", func() { It("fails if the targeted stack isn't run again", func() { refetch(useRabbitStack) // this is fetched above; but, avoid future coincidences .. useRabbitStack.Spec.Refresh = true - waitForStackSince = time.Now() + resetWaitForStack() Expect(k8sClient.Update(context.TODO(), useRabbitStack)).To(Succeed()) time.Sleep(30 * time.Second) @@ -237,11 +234,11 @@ var _ = When("a stack uses a provider with credentials kept in state", func() { { Name: targetedStack.Name, Requirement: &shared.RequirementSpec{ - SucceededWithinDuration: &metav1.Duration{10 * time.Minute}, + SucceededWithinDuration: &metav1.Duration{Duration: 10 * time.Minute}, }, }, } - waitForStackSince = time.Now() + resetWaitForStack() Expect(k8sClient.Update(ctx, useRabbitStack)).To(Succeed()) // TODO check that it's marked as reconciling pending a prerequisite diff --git a/test/suite_test.go b/test/suite_test.go index d0e7bb83..fb4d4858 100644 --- a/test/suite_test.go +++ b/test/suite_test.go @@ -29,7 +29,6 @@ import ( apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" @@ -47,7 +46,9 @@ import ( // These tests use Ginkgo (BDD-style Go testing framework). Refer to // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -var cfg *rest.Config +// namespace is the namespace in which the tests are run. +const namespace = "default" + var k8sClient client.Client var k8sManager ctrl.Manager var testEnv *envtest.Environment @@ -157,9 +158,10 @@ func writeKubeconfig(targetDir string) string { return kubeconfig } +// removeTempDir is a convenience for cleaning up after writeKubeconfig. func removeTempDir(tmp string) { if strings.HasPrefix(tmp, os.TempDir()) { - os.RemoveAll(tmp) + Expect(os.RemoveAll(tmp)).To(Succeed()) } } @@ -212,6 +214,7 @@ func deleteAndWaitForFinalization(obj client.Object) { EventuallyWithOffset(1, func() bool { err := k8sClient.Get(context.TODO(), key, obj) if err == nil { + // If we can still get the object, it hasn't been finalized yet. return false } ExpectWithOffset(2, client.IgnoreNotFound(err)).To(BeNil()) diff --git a/test/testdata/run-rabbitmq/package.json b/test/testdata/run-rabbitmq/package.json index 54e09367..54bf7b11 100644 --- a/test/testdata/run-rabbitmq/package.json +++ b/test/testdata/run-rabbitmq/package.json @@ -3,7 +3,7 @@ "main": "index.js", "dependencies": { "@pulumi/docker": "^3.4.1", - "@pulumi/kubernetes": "^3.0.0", + "@pulumi/kubernetes": "3.26.0", "@pulumi/pulumi": "^3.0.0", "@pulumi/random": "^4.8.2" } diff --git a/test/testdata/test-program-changed.yaml b/test/testdata/test-program-changed.yaml deleted file mode 100644 index 2abf3d0f..00000000 --- a/test/testdata/test-program-changed.yaml +++ /dev/null @@ -1,19 +0,0 @@ -configuration: - foo: - type: String - default: "different" -resources: - provider: - type: pulumi:providers:kubernetes - example: - type: kubernetes:core/v1:ConfigMap - properties: - metadata: - annotations: - pulumi.com/patchForce: "true" - name: - test-configmap - data: - foo: ${foo} - options: - provider: ${provider} diff --git a/test/testdata/test-program-invalid.yaml b/test/testdata/test-program-invalid.yaml deleted file mode 100644 index 605804de..00000000 --- a/test/testdata/test-program-invalid.yaml +++ /dev/null @@ -1,13 +0,0 @@ -resources: - example: - type: kubernetes:core/v1:ConfigMap - properties: - metadata: - annotations: - pulumi.com/patchForce: "true" - name: - test-configmap - data: - foo: bar - options: - provider: ${provider} diff --git a/test/testdata/test-program.yaml b/test/testdata/test-program.yaml deleted file mode 100644 index 6eee55a1..00000000 --- a/test/testdata/test-program.yaml +++ /dev/null @@ -1,19 +0,0 @@ -configuration: - foo: - type: "String" - default: "bar" -resources: - provider: - type: pulumi:providers:kubernetes - example: - type: kubernetes:core/v1:ConfigMap - properties: - metadata: - annotations: - pulumi.com/patchForce: "true" - name: - test-configmap - data: - foo: ${foo} - options: - provider: ${provider} diff --git a/test/testdata/use-rabbitmq/package.json b/test/testdata/use-rabbitmq/package.json index d0226915..773f8a6e 100644 --- a/test/testdata/use-rabbitmq/package.json +++ b/test/testdata/use-rabbitmq/package.json @@ -2,7 +2,7 @@ "name": "use-rabbitmq", "main": "index.js", "dependencies": { - "@pulumi/kubernetes": "^3.0.0", + "@pulumi/kubernetes": "3.26.0", "@pulumi/pulumi": "^3.0.0", "@pulumi/rabbitmq": "^3.2.0" }