diff --git a/.tekton/rosa-cli-e2e-test-pull-request.yaml b/.tekton/rosa-cli-e2e-test-pull-request.yaml index 4fb2b718ed..c6fcda6717 100644 --- a/.tekton/rosa-cli-e2e-test-pull-request.yaml +++ b/.tekton/rosa-cli-e2e-test-pull-request.yaml @@ -162,7 +162,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:12cbcf0b408e906f84e7eb3c62c6cd618e2b1f78a40218e10940fbaf2c45455d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:7759aab088034f32df156db44569690442a85559b982f7a1a9c925a1ad42e650 - name: kind value: task resolver: bundles @@ -272,7 +272,7 @@ spec: - name: name value: source-build-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:7c5575ac8e292f27f57716c021ab0324460dc958e73946724c588c5228e5f372 + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:5f53518629ce04fee0466d25670700d0f36b2dbd296b6ae04eaad5d44f0d7d52 - name: kind value: task resolver: bundles @@ -535,7 +535,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:3ab844157eccd68e95e4852adc06c3c4ea674edb7865a474b0a898227f2893d6 + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:86170d1f69fa75c725952b083311f8107d6334f61b505c4a03213b59fd3199ff - name: kind value: task resolver: bundles diff --git a/.tekton/rosa-cli-e2e-test-push.yaml b/.tekton/rosa-cli-e2e-test-push.yaml index 1c3a9e0fb5..a5c955a0de 100644 --- a/.tekton/rosa-cli-e2e-test-push.yaml +++ b/.tekton/rosa-cli-e2e-test-push.yaml @@ -159,7 +159,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:12cbcf0b408e906f84e7eb3c62c6cd618e2b1f78a40218e10940fbaf2c45455d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:7759aab088034f32df156db44569690442a85559b982f7a1a9c925a1ad42e650 - name: kind value: task resolver: bundles @@ -269,7 +269,7 @@ spec: - name: name value: source-build-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:7c5575ac8e292f27f57716c021ab0324460dc958e73946724c588c5228e5f372 + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:5f53518629ce04fee0466d25670700d0f36b2dbd296b6ae04eaad5d44f0d7d52 - name: kind value: task resolver: bundles @@ -532,7 +532,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:3ab844157eccd68e95e4852adc06c3c4ea674edb7865a474b0a898227f2893d6 + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:86170d1f69fa75c725952b083311f8107d6334f61b505c4a03213b59fd3199ff - name: kind value: task resolver: bundles diff --git a/.tekton/rosa-pull-request.yaml b/.tekton/rosa-pull-request.yaml index 53c6262342..df24f69cf4 100644 --- a/.tekton/rosa-pull-request.yaml +++ b/.tekton/rosa-pull-request.yaml @@ -158,7 +158,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:12cbcf0b408e906f84e7eb3c62c6cd618e2b1f78a40218e10940fbaf2c45455d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:7759aab088034f32df156db44569690442a85559b982f7a1a9c925a1ad42e650 - name: kind value: task resolver: bundles @@ -266,7 +266,7 @@ spec: - name: name value: source-build-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:7c5575ac8e292f27f57716c021ab0324460dc958e73946724c588c5228e5f372 + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:5f53518629ce04fee0466d25670700d0f36b2dbd296b6ae04eaad5d44f0d7d52 - name: kind value: task resolver: bundles @@ -526,7 +526,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:3ab844157eccd68e95e4852adc06c3c4ea674edb7865a474b0a898227f2893d6 + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:86170d1f69fa75c725952b083311f8107d6334f61b505c4a03213b59fd3199ff - name: kind value: task resolver: bundles diff --git a/.tekton/rosa-push.yaml b/.tekton/rosa-push.yaml index 34280d4607..d16ebd49ef 100644 --- a/.tekton/rosa-push.yaml +++ b/.tekton/rosa-push.yaml @@ -155,7 +155,7 @@ spec: - name: name value: git-clone-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:12cbcf0b408e906f84e7eb3c62c6cd618e2b1f78a40218e10940fbaf2c45455d + value: quay.io/konflux-ci/tekton-catalog/task-git-clone-oci-ta:0.2@sha256:7759aab088034f32df156db44569690442a85559b982f7a1a9c925a1ad42e650 - name: kind value: task resolver: bundles @@ -263,7 +263,7 @@ spec: - name: name value: source-build-oci-ta - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:7c5575ac8e292f27f57716c021ab0324460dc958e73946724c588c5228e5f372 + value: quay.io/konflux-ci/tekton-catalog/task-source-build-oci-ta:0.3@sha256:5f53518629ce04fee0466d25670700d0f36b2dbd296b6ae04eaad5d44f0d7d52 - name: kind value: task resolver: bundles @@ -526,7 +526,7 @@ spec: - name: name value: apply-tags - name: bundle - value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:3ab844157eccd68e95e4852adc06c3c4ea674edb7865a474b0a898227f2893d6 + value: quay.io/konflux-ci/tekton-catalog/task-apply-tags:0.3@sha256:86170d1f69fa75c725952b083311f8107d6334f61b505c4a03213b59fd3199ff - name: kind value: task resolver: bundles diff --git a/cmd/create/oidcconfig/cmd_test.go b/cmd/create/oidcconfig/cmd_test.go new file mode 100644 index 0000000000..5489345c9a --- /dev/null +++ b/cmd/create/oidcconfig/cmd_test.go @@ -0,0 +1,100 @@ +package oidcconfig + +import ( + "net/http" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/openshift-online/ocm-common/pkg/rosa/oidcconfigs" + . "github.com/openshift-online/ocm-sdk-go/testing" + + "github.com/openshift/rosa/pkg/interactive" + "github.com/openshift/rosa/pkg/test" +) + +var _ = Describe("Create OIDC Config", func() { + Context("getOidcConfigStrategy", func() { + var input *oidcconfigs.OidcConfigInput + + BeforeEach(func() { + input = &oidcconfigs.OidcConfigInput{} + args.rawFiles = false + args.managed = false + }) + + It("returns raw strategy when rawFiles is true", func() { + args.rawFiles = true + + strategy, err := getOidcConfigStrategy(interactive.ModeAuto, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&CreateUnmanagedOidcConfigRawStrategy{})) + }) + + It("returns managed auto strategy when managed is true", func() { + args.managed = true + + strategy, err := getOidcConfigStrategy(interactive.ModeAuto, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&CreateManagedOidcConfigAutoStrategy{})) + }) + + It("returns unmanaged auto strategy for auto mode", func() { + strategy, err := getOidcConfigStrategy(interactive.ModeAuto, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&CreateUnmanagedOidcConfigAutoStrategy{})) + }) + + It("returns unmanaged manual strategy for manual mode", func() { + strategy, err := getOidcConfigStrategy(interactive.ModeManual, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&CreateUnmanagedOidcConfigManualStrategy{})) + }) + + It("returns error for invalid mode", func() { + _, err := getOidcConfigStrategy("invalid", input) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Invalid mode")) + }) + }) + + Context("ManagedOidcConfigAutoStrategy.executeNoExit", func() { + var t *test.TestingRuntime + + BeforeEach(func() { + t = test.NewTestRuntime() + }) + + It("returns the OIDC config ID on success", func() { + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, `{ + "kind": "OidcConfig", + "id": "managed-oidc-123", + "managed": true, + "issuer_url": "https://oidc.managed.example.com" + }`)) + + input := &oidcconfigs.OidcConfigInput{} + strategy := &CreateManagedOidcConfigAutoStrategy{oidcConfigInput: input} + + id, err := strategy.executeNoExit(t.RosaRuntime) + Expect(err).NotTo(HaveOccurred()) + Expect(id).To(Equal("managed-oidc-123")) + }) + + It("returns error when CreateOidcConfig fails", func() { + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusInternalServerError, `{ + "kind": "Error", + "id": "500", + "href": "/api/clusters_mgmt/v1/errors/500", + "code": "CLUSTERS-MGMT-500", + "reason": "internal error" + }`)) + + input := &oidcconfigs.OidcConfigInput{} + strategy := &CreateManagedOidcConfigAutoStrategy{oidcConfigInput: input} + + _, err := strategy.executeNoExit(t.RosaRuntime) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("managed OIDC Configuration")) + }) + }) +}) diff --git a/cmd/create/oidcconfig/oidcconfig_suite_test.go b/cmd/create/oidcconfig/oidcconfig_suite_test.go new file mode 100644 index 0000000000..fc8e43bb42 --- /dev/null +++ b/cmd/create/oidcconfig/oidcconfig_suite_test.go @@ -0,0 +1,13 @@ +package oidcconfig + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestOidcConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Create OidcConfig Suite") +} diff --git a/cmd/create/oidcprovider/cmd_test.go b/cmd/create/oidcprovider/cmd_test.go new file mode 100644 index 0000000000..3ca721482c --- /dev/null +++ b/cmd/create/oidcprovider/cmd_test.go @@ -0,0 +1,118 @@ +package oidcprovider + +import ( + "fmt" + "net/http" + + "go.uber.org/mock/gomock" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/openshift-online/ocm-sdk-go/testing" + + awsClient "github.com/openshift/rosa/pkg/aws" + "github.com/openshift/rosa/pkg/test" +) + +var _ = Describe("Create OIDC Provider", func() { + Context("CreateOIDCProvider", func() { + var t *test.TestingRuntime + + BeforeEach(func() { + t = test.NewTestRuntime() + }) + + It("creates the provider successfully", func() { + oidcConfigId := "oidc-config-123" + issuerUrl := "https://oidc.example.com/abc123" + thumbprint := "a]b]c]d]e]f]0]1]2]3]4]5]6]7]8]9]a]b]c]d" + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, fmt.Sprintf(`{ + "kind": "OidcConfig", + "id": "%s", + "issuer_url": "%s" + }`, oidcConfigId, issuerUrl))) + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, fmt.Sprintf(`{ + "kind": "OidcThumbprint", + "thumbprint": "%s", + "oidc_config_id": "%s" + }`, thumbprint, oidcConfigId))) + + mockAWS := t.RosaRuntime.AWSClient.(*awsClient.MockClient) + mockAWS.EXPECT().CreateOpenIDConnectProvider( + issuerUrl, + thumbprint, + gomock.Any(), + ).Return("arn:aws:iam::123456789012:oidc-provider/oidc.example.com/abc123", nil) + + err := CreateOIDCProvider(t.RosaRuntime, oidcConfigId, "", true) + Expect(err).NotTo(HaveOccurred()) + }) + + It("returns error when GetOidcConfig fails", func() { + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusNotFound, `{ + "kind": "Error", + "id": "404", + "href": "/api/clusters_mgmt/v1/errors/404", + "code": "CLUSTERS-MGMT-404", + "reason": "not found" + }`)) + + err := CreateOIDCProvider(t.RosaRuntime, "nonexistent", "", true) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("retrieving OIDC Config")) + }) + + It("returns error when FetchOidcThumbprint fails", func() { + oidcConfigId := "oidc-config-123" + issuerUrl := "https://oidc.example.com/abc123" + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, fmt.Sprintf(`{ + "kind": "OidcConfig", + "id": "%s", + "issuer_url": "%s" + }`, oidcConfigId, issuerUrl))) + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusInternalServerError, `{ + "kind": "Error", + "id": "500", + "href": "/api/clusters_mgmt/v1/errors/500", + "code": "CLUSTERS-MGMT-500", + "reason": "thumbprint service unavailable" + }`)) + + err := CreateOIDCProvider(t.RosaRuntime, oidcConfigId, "", true) + Expect(err).To(HaveOccurred()) + }) + + It("returns error when CreateOpenIDConnectProvider fails", func() { + oidcConfigId := "oidc-config-123" + issuerUrl := "https://oidc.example.com/abc123" + thumbprint := "a]b]c]d]e]f]0]1]2]3]4]5]6]7]8]9]a]b]c]d" + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, fmt.Sprintf(`{ + "kind": "OidcConfig", + "id": "%s", + "issuer_url": "%s" + }`, oidcConfigId, issuerUrl))) + + t.ApiServer.AppendHandlers(RespondWithJSON(http.StatusOK, fmt.Sprintf(`{ + "kind": "OidcThumbprint", + "thumbprint": "%s", + "oidc_config_id": "%s" + }`, thumbprint, oidcConfigId))) + + mockAWS := t.RosaRuntime.AWSClient.(*awsClient.MockClient) + mockAWS.EXPECT().CreateOpenIDConnectProvider( + issuerUrl, + thumbprint, + gomock.Any(), + ).Return("", fmt.Errorf("access denied")) + + err := CreateOIDCProvider(t.RosaRuntime, oidcConfigId, "", true) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("access denied")) + }) + }) +}) diff --git a/cmd/create/oidcprovider/oidcprovider_suite_test.go b/cmd/create/oidcprovider/oidcprovider_suite_test.go new file mode 100644 index 0000000000..6a287c221e --- /dev/null +++ b/cmd/create/oidcprovider/oidcprovider_suite_test.go @@ -0,0 +1,13 @@ +package oidcprovider + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestCreateOidcProvider(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Create OidcProvider Suite") +} diff --git a/cmd/dlt/oidcconfig/cmd_test.go b/cmd/dlt/oidcconfig/cmd_test.go new file mode 100644 index 0000000000..ba8c1cba43 --- /dev/null +++ b/cmd/dlt/oidcconfig/cmd_test.go @@ -0,0 +1,44 @@ +package oidcconfig + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/openshift/rosa/pkg/interactive" +) + +var _ = Describe("Delete OIDC Config", func() { + Context("getOidcConfigStrategy", func() { + It("returns managed strategy when input is managed", func() { + input := OidcConfigInput{Managed: true} + + strategy, err := getOidcConfigStrategy(interactive.ModeAuto, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&deleteManagedOidcConfigStrategy{})) + }) + + It("returns unmanaged auto strategy for auto mode", func() { + input := OidcConfigInput{Managed: false, BucketName: "test-bucket"} + + strategy, err := getOidcConfigStrategy(interactive.ModeAuto, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&deleteUnmanagedOidcConfigAutoStrategy{})) + }) + + It("returns unmanaged manual strategy for manual mode", func() { + input := OidcConfigInput{Managed: false, BucketName: "test-bucket"} + + strategy, err := getOidcConfigStrategy(interactive.ModeManual, input) + Expect(err).NotTo(HaveOccurred()) + Expect(strategy).To(BeAssignableToTypeOf(&deleteUnmanagedOidcConfigManualStrategy{})) + }) + + It("returns error for invalid mode", func() { + input := OidcConfigInput{Managed: false} + + _, err := getOidcConfigStrategy("invalid", input) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Invalid mode")) + }) + }) +}) diff --git a/cmd/dlt/oidcconfig/oidcconfig_suite_test.go b/cmd/dlt/oidcconfig/oidcconfig_suite_test.go new file mode 100644 index 0000000000..583fa0049a --- /dev/null +++ b/cmd/dlt/oidcconfig/oidcconfig_suite_test.go @@ -0,0 +1,13 @@ +package oidcconfig + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestDeleteOidcConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Delete OidcConfig Suite") +}