11/*
22Copyright 2025.
3-
43Licensed under the Apache License, Version 2.0 (the "License");
54you may not use this file except in compliance with the License.
65You may obtain a copy of the License at
76
8- http://www.apache.org/licenses/LICENSE-2.0
7+ http://www.apache.org/licenses/LICENSE-2.0
98
109Unless required by applicable law or agreed to in writing, software
1110distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,66 +16,147 @@ limitations under the License.
1716package e2e
1817
1918import (
19+ "context"
20+ "embed"
21+ "encoding/base64"
2022 "fmt"
21- "os/exec "
23+ "testing "
2224 "time"
2325
26+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+ "k8s.io/apimachinery/pkg/runtime/schema"
28+ "k8s.io/client-go/dynamic"
29+ "k8s.io/client-go/kubernetes"
30+
2431 . "github.com/onsi/ginkgo/v2"
2532 . "github.com/onsi/gomega"
2633
2734 "github.com/openshift/external-secrets-operator/test/utils"
2835)
2936
30- const namespace = "external-secrets-operator"
37+ //go:embed testdata/*
38+ var testassets embed.FS
39+
40+ const (
41+ operatorNamespace = "external-secrets-operator"
42+ operandNamespace = "external-secrets"
43+ secretStoreFile = "testdata/aws_secret_store.yaml"
44+ externalSecretFile = "testdata/aws_external_secret.yaml"
45+ pushSecretFile = "testdata/push_secret.yaml"
46+ externalSecrets = "testdata/external_secret.yaml"
47+ expectedSecretValueFile = "testdata/expected_value.yaml"
48+ awsSecretToPushFile = "testdata/aws_k8s_push_secret.yaml"
49+ awsSecretRegionName = "ap-south-1"
50+ )
51+
52+ var _ = Describe ("External Secrets Operator End-to-End test scenarios" , Ordered , func () {
53+ ctx := context .TODO ()
54+ var (
55+ clientset * kubernetes.Clientset
56+ dynamicClient * dynamic.DynamicClient
57+ loader utils.DynamicResourceLoader
58+ awsSecretName string
59+ )
3160
32- var _ = Describe ("controller" , Ordered , func () {
3361 BeforeAll (func () {
34- //TODO: add any pre-reqs for the tests.
62+ var err error
63+ loader = utils .NewDynamicResourceLoader (ctx , & testing.T {})
64+
65+ clientset , err = kubernetes .NewForConfig (cfg )
66+ Expect (err ).Should (BeNil ())
67+
68+ dynamicClient , err = dynamic .NewForConfig (cfg )
69+ Expect (err ).Should (BeNil ())
70+
71+ awsSecretName = fmt .Sprintf ("eso-e2e-secret-%s" , utils .GetRandomString (5 ))
72+
73+ By ("Waiting for external-secrets-operator controller-manager pod to be ready" )
74+ Expect (utils .VerifyPodsReadyByPrefix (ctx , clientset , operatorNamespace , []string {
75+ "external-secrets-operator-controller-manager-" ,
76+ })).To (Succeed ())
77+
78+ By ("Creating the externalsecrets.openshift.operator.io/cluster CR" )
79+ loader .CreateFromFile (testassets .ReadFile , externalSecrets , operatorNamespace )
3580 })
3681
3782 AfterAll (func () {
38- //TODO: add any clean up required after the tests.
83+ By ("Deleting the externalsecrets.openshift.operator.io/cluster CR" )
84+ loader .DeleteFromFile (testassets .ReadFile , externalSecrets , operatorNamespace )
85+
86+ err := utils .DeleteAWSSecret (ctx , clientset , awsSecretName , awsSecretRegionName )
87+ Expect (err ).NotTo (HaveOccurred (), "failed to delete AWS secret test/e2e" )
3988 })
4089
41- Context ("Operator" , func () {
42- It ("should run successfully" , func () {
43- var controllerPodName string
44-
45- By ("validating that the controller-manager pod is running as expected" )
46- verifyControllerUp := func () error {
47- // Get pod name
48-
49- cmd := exec .Command ("oc" , "get" ,
50- "pods" , "-l" , "control-plane=controller-manager" ,
51- "-o" , "go-template={{ range .items }}" +
52- "{{ if not .metadata.deletionTimestamp }}" +
53- "{{ .metadata.name }}" +
54- "{{ \" \\ n\" }}{{ end }}{{ end }}" ,
55- "-n" , namespace ,
56- )
57-
58- podOutput , err := utils .Run (cmd )
59- ExpectWithOffset (2 , err ).NotTo (HaveOccurred ())
60- podNames := utils .GetNonEmptyLines (string (podOutput ))
61- if len (podNames ) != 1 {
62- return fmt .Errorf ("expect 1 controller pods running, but got %d" , len (podNames ))
63- }
64- controllerPodName = podNames [0 ]
65- ExpectWithOffset (2 , controllerPodName ).Should (ContainSubstring ("controller-manager" ))
66-
67- // Validate pod status
68- cmd = exec .Command ("oc" , "get" ,
69- "pods" , controllerPodName , "-o" , "jsonpath={.status.phase}" ,
70- "-n" , namespace ,
71- )
72- status , err := utils .Run (cmd )
73- ExpectWithOffset (2 , err ).NotTo (HaveOccurred ())
74- if string (status ) != "Running" {
75- return fmt .Errorf ("controller pod in %s status" , status )
76- }
77- return nil
78- }
79- EventuallyWithOffset (1 , verifyControllerUp , time .Minute , time .Second ).Should (Succeed ())
80- })
90+ BeforeEach (func () {
91+ By ("Verifying ESO pods are running and ready" )
92+ Expect (utils .VerifyPodsReadyByPrefix (ctx , clientset , operandNamespace , []string {
93+ "external-secrets-" ,
94+ "external-secrets-cert-controller-" ,
95+ "external-secrets-webhook-" ,
96+ })).To (Succeed ())
97+ })
98+
99+ It ("should create secrets mentioned in ExternalSecret using the referenced SecretStore" , func () {
100+ expectedSecretValue , err := utils .ReadExpectedSecretValue (expectedSecretValueFile )
101+ Expect (err ).To (Succeed ())
102+
103+ By ("Creating kubernetes secret to be used in PushSecret" )
104+ secretsAssetFunc := utils .ReplacePatternInAsset ("${SECRET_VALUE}" , base64 .StdEncoding .EncodeToString (expectedSecretValue ))
105+ loader .CreateFromFile (secretsAssetFunc , awsSecretToPushFile , operandNamespace )
106+ defer loader .DeleteFromFile (testassets .ReadFile , awsSecretToPushFile , operandNamespace )
107+
108+ By ("Creating SecretStore" )
109+ loader .CreateFromFile (testassets .ReadFile , secretStoreFile , operandNamespace )
110+ defer loader .DeleteFromFile (testassets .ReadFile , secretStoreFile , operandNamespace )
111+
112+ By ("Waiting for SecretStore to become Ready" )
113+ Expect (utils .WaitForESOResourceReady (ctx , dynamicClient ,
114+ schema.GroupVersionResource {
115+ Group : "external-secrets.io" ,
116+ Version : "v1beta1" ,
117+ Resource : "clustersecretstores" ,
118+ },
119+ "" , "aws-secret-store" , time .Minute ,
120+ )).To (Succeed ())
121+
122+ By ("Creating PushSecret" )
123+ assetFunc := utils .ReplacePatternInAsset ("${AWS_SECRET_KEY_NAME}" , awsSecretName )
124+ loader .CreateFromFile (assetFunc , pushSecretFile , operandNamespace )
125+ defer loader .DeleteFromFile (testassets .ReadFile , pushSecretFile , operandNamespace )
126+
127+ By ("Waiting for PushSecret to become Ready" )
128+ Expect (utils .WaitForESOResourceReady (ctx , dynamicClient ,
129+ schema.GroupVersionResource {
130+ Group : "external-secrets.io" ,
131+ Version : "v1alpha1" ,
132+ Resource : "pushsecrets" ,
133+ },
134+ operandNamespace , "aws-push-secret" , time .Minute ,
135+ )).To (Succeed ())
136+
137+ By ("Creating ExternalSecret" )
138+ loader .CreateFromFile (assetFunc , externalSecretFile , operandNamespace )
139+ defer loader .DeleteFromFile (testassets .ReadFile , externalSecretFile , operandNamespace )
140+
141+ By ("Waiting for ExternalSecret to become Ready" )
142+ Expect (utils .WaitForESOResourceReady (ctx , dynamicClient ,
143+ schema.GroupVersionResource {
144+ Group : "external-secrets.io" ,
145+ Version : "v1beta1" ,
146+ Resource : "externalsecrets" ,
147+ },
148+ operandNamespace , "aws-external-secret" , time .Minute ,
149+ )).To (Succeed ())
150+
151+ By ("Waiting for target secret to be created with expected data" )
152+ Eventually (func (g Gomega ) {
153+ secret , err := loader .KubeClient .CoreV1 ().Secrets (operandNamespace ).Get (ctx , "aws-secret" , metav1.GetOptions {})
154+ g .Expect (err ).NotTo (HaveOccurred (), "should get aws-secret from namespace %s" , operandNamespace )
155+
156+ val , ok := secret .Data ["aws_secret_access_key" ]
157+ g .Expect (ok ).To (BeTrue (), "aws_secret_access_key should be present in secret %s" , secret .Name )
158+
159+ g .Expect (val ).To (Equal (expectedSecretValue ), "aws_secret_access_key does not match expected value" )
160+ }, time .Minute , 10 * time .Second ).Should (Succeed ())
81161 })
82162})
0 commit comments