@@ -3,22 +3,34 @@ package e2e
33import (
44 "context"
55 "fmt"
6+ "io"
7+ "os"
8+ "path/filepath"
9+ "strings"
610 "time"
711
812 . "github.com/onsi/ginkgo/v2"
913 . "github.com/onsi/gomega"
1014 catalogd "github.com/operator-framework/catalogd/pkg/apis/core/v1beta1"
1115 operatorv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
1216 rukpakv1alpha1 "github.com/operator-framework/rukpak/api/v1alpha1"
17+ "gopkg.in/yaml.v2"
18+ appsv1 "k8s.io/api/apps/v1"
19+ corev1 "k8s.io/api/core/v1"
20+ v1 "k8s.io/api/core/v1"
1321 apimeta "k8s.io/apimachinery/pkg/api/meta"
1422 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1523 "k8s.io/apimachinery/pkg/types"
1624 "k8s.io/apimachinery/pkg/util/rand"
25+ kubeclient "k8s.io/client-go/kubernetes"
26+ "k8s.io/utils/env"
27+ "sigs.k8s.io/controller-runtime/pkg/client"
1728)
1829
1930const (
20- defaultTimeout = 30 * time .Second
21- defaultPoll = 1 * time .Second
31+ defaultTimeout = 30 * time .Second
32+ defaultPoll = 1 * time .Second
33+ artifactTestName = "operator-controller-e2e"
2234)
2335
2436var _ = Describe ("Operator Install" , func () {
@@ -99,10 +111,132 @@ var _ = Describe("Operator Install", func() {
99111
100112 })
101113 AfterEach (func () {
114+ if basePath := env .GetString ("ARTIFACT_PATH" , "" ); basePath != "" {
115+ // get all the artifacts from the test run and save them to the artifact path
116+ getArtifactsOutput (ctx , basePath )
117+ }
102118 err := c .Delete (ctx , operatorCatalog )
103119 Expect (err ).ToNot (HaveOccurred ())
104120 err = c .Delete (ctx , operator )
105121 Expect (err ).ToNot (HaveOccurred ())
106122 })
107123 })
108124})
125+
126+ // getArtifactsOutput gets all the artifacts from the test run and saves them to the artifact path.
127+ // right now it will save:
128+ // - operators
129+ // - pods logs
130+ // - deployments
131+ // - bundle
132+ // - bundledeployments
133+ // - catalogsources
134+
135+ func getArtifactsOutput (ctx context.Context , basePath string ) {
136+ kubeClient , err := kubeclient .NewForConfig (cfg )
137+ Expect (err ).To (Not (HaveOccurred ()))
138+
139+ artifactPath := filepath .Join (basePath , artifactTestName , fmt .Sprint (time .Now ().UnixNano ()))
140+
141+ // Create the full artifact path
142+ err = os .MkdirAll (artifactPath , 0755 )
143+ Expect (err ).To (Not (HaveOccurred ()))
144+
145+ // Get all namespaces
146+ namespaces := corev1.NamespaceList {}
147+ err = c .List (ctx , & namespaces )
148+ Expect (err ).To (Not (HaveOccurred ()))
149+
150+ // get all operators save them to the artifact path.
151+ operators := operatorv1alpha1.OperatorList {}
152+ err = c .List (ctx , & operators , client .InNamespace ("" ))
153+ Expect (err ).To (Not (HaveOccurred ()))
154+ for _ , operator := range operators .Items {
155+ // Save operator to artifact path
156+ operatorYaml , err := yaml .Marshal (operator )
157+ Expect (err ).To (Not (HaveOccurred ()))
158+ err = os .WriteFile (filepath .Join (artifactPath , operator .Name + "-operator.yaml" ), operatorYaml , 0644 )
159+ Expect (err ).To (Not (HaveOccurred ()))
160+ }
161+
162+ // get all catalogsources save them to the artifact path.
163+ catalogsources := catalogd.CatalogSourceList {}
164+ err = c .List (ctx , & catalogsources , client .InNamespace ("" ))
165+ Expect (err ).To (Not (HaveOccurred ()))
166+ for _ , catalogsource := range catalogsources .Items {
167+ // Save catalogsource to artifact path
168+ catalogsourceYaml , err := yaml .Marshal (catalogsource )
169+ Expect (err ).To (Not (HaveOccurred ()))
170+ err = os .WriteFile (filepath .Join (artifactPath , catalogsource .Name + "-catalogsource.yaml" ), catalogsourceYaml , 0644 )
171+ Expect (err ).To (Not (HaveOccurred ()))
172+ }
173+
174+ // Get all Bundles in the namespace and save them to the artifact path.
175+ bundles := rukpakv1alpha1.BundleList {}
176+ err = c .List (ctx , & bundles , client .InNamespace ("" ))
177+ Expect (err ).To (Not (HaveOccurred ()))
178+ for _ , bundle := range bundles .Items {
179+ // Save bundle to artifact path
180+ bundleYaml , err := yaml .Marshal (bundle )
181+ Expect (err ).To (Not (HaveOccurred ()))
182+ err = os .WriteFile (filepath .Join (artifactPath , bundle .Name + "-bundle.yaml" ), bundleYaml , 0644 )
183+ Expect (err ).To (Not (HaveOccurred ()))
184+ }
185+
186+ // Get all BundleDeployments in the namespace and save them to the artifact path.
187+ bundleDeployments := rukpakv1alpha1.BundleDeploymentList {}
188+ err = c .List (ctx , & bundleDeployments , client .InNamespace ("" ))
189+ Expect (err ).To (Not (HaveOccurred ()))
190+ for _ , bundleDeployment := range bundleDeployments .Items {
191+ // Save bundleDeployment to artifact path
192+ bundleDeploymentYaml , err := yaml .Marshal (bundleDeployment )
193+ Expect (err ).To (Not (HaveOccurred ()))
194+ err = os .WriteFile (filepath .Join (artifactPath , bundleDeployment .Name + "-bundleDeployment.yaml" ), bundleDeploymentYaml , 0644 )
195+ Expect (err ).To (Not (HaveOccurred ()))
196+ }
197+
198+ for _ , namespace := range namespaces .Items {
199+ // let's ignore kube-* namespaces.
200+ if strings .Contains (namespace .Name , "kube-" ) {
201+ continue
202+ }
203+
204+ namespaceArtifactPath := filepath .Join (artifactPath , namespace .Name )
205+ err = os .Mkdir (namespaceArtifactPath , 0755 )
206+ Expect (err ).To (Not (HaveOccurred ()))
207+
208+ // get all deployments in the namespace and save them to the artifact path.
209+ deployments := appsv1.DeploymentList {}
210+ err = c .List (ctx , & deployments , client .InNamespace (namespace .Name ))
211+ Expect (err ).To (Not (HaveOccurred ()))
212+ for _ , deployment := range deployments .Items {
213+ // Save deployment to artifact path
214+ deploymentYaml , err := yaml .Marshal (deployment )
215+ Expect (err ).To (Not (HaveOccurred ()))
216+ err = os .WriteFile (filepath .Join (namespaceArtifactPath , deployment .Name + "-deployment.yaml" ), deploymentYaml , 0644 )
217+ Expect (err ).To (Not (HaveOccurred ()))
218+ }
219+
220+ // Get logs from all pods in all namespaces
221+ pods := corev1.PodList {}
222+ err = c .List (ctx , & pods , client .InNamespace (namespace .Name ))
223+ Expect (err ).To (Not (HaveOccurred ()))
224+ for _ , pod := range pods .Items {
225+ if pod .Status .Phase != v1 .PodRunning && pod .Status .Phase != v1 .PodSucceeded && pod .Status .Phase != v1 .PodFailed {
226+ continue
227+ }
228+ for _ , container := range pod .Spec .Containers {
229+ logs , err := kubeClient .CoreV1 ().Pods (namespace .Name ).GetLogs (pod .Name , & v1.PodLogOptions {Container : container .Name }).Stream (ctx )
230+ Expect (err ).To (Not (HaveOccurred ()))
231+ defer logs .Close ()
232+
233+ outFile , err := os .Create (filepath .Join (namespaceArtifactPath , pod .Name + "-" + container .Name + "-logs.txt" ))
234+ Expect (err ).To (Not (HaveOccurred ()))
235+ defer outFile .Close ()
236+
237+ _ , err = io .Copy (outFile , logs )
238+ Expect (err ).To (Not (HaveOccurred ()))
239+ }
240+ }
241+ }
242+ }
0 commit comments