github.com/operator-framework/operator-lifecycle-manager@v0.30.0/test/e2e/ctx/ctx.go (about) 1 package ctx 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "path/filepath" 8 9 "github.com/operator-framework/operator-lifecycle-manager/test/e2e/util" 10 appsv1 "k8s.io/api/apps/v1" 11 apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 12 13 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 14 "k8s.io/apimachinery/pkg/runtime" 15 "k8s.io/client-go/dynamic" 16 kscheme "k8s.io/client-go/kubernetes/scheme" 17 "k8s.io/client-go/rest" 18 k8scontrollerclient "sigs.k8s.io/controller-runtime/pkg/client" 19 20 operatorsv1 "github.com/operator-framework/api/pkg/operators/v1" 21 operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" 22 operatorsv2 "github.com/operator-framework/api/pkg/operators/v2" 23 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" 24 controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client" 25 "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient" 26 pversioned "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/client/clientset/versioned" 27 ) 28 29 var ctx TestContext 30 31 // TestContext represents the environment of an executing test. It can 32 // be considered roughly analogous to a kubeconfig context. 33 type TestContext struct { 34 restConfig *rest.Config 35 kubeClient operatorclient.ClientInterface 36 operatorClient versioned.Interface 37 dynamicClient dynamic.Interface 38 packageClient pversioned.Interface 39 e2eClient *util.E2EKubeClient 40 ssaClient *controllerclient.ServerSideApplier 41 42 kubeconfigPath string 43 artifactsDir string 44 artifactsScriptPath string 45 46 scheme *runtime.Scheme 47 48 // client is the controller-runtime client -- we should use this from now on 49 client k8scontrollerclient.Client 50 } 51 52 // Ctx returns a pointer to the global test context. During parallel 53 // test executions, Ginkgo starts one process per test "node", and 54 // each node will have its own context, which may or may not point to 55 // the same test cluster. 56 func Ctx() *TestContext { 57 return &ctx 58 } 59 60 func (ctx TestContext) Logf(f string, v ...interface{}) { 61 util.Logf(f, v...) 62 } 63 64 func (ctx TestContext) Scheme() *runtime.Scheme { 65 return ctx.scheme 66 } 67 68 func (ctx TestContext) RESTConfig() *rest.Config { 69 return rest.CopyConfig(ctx.restConfig) 70 } 71 72 func (ctx TestContext) KubeClient() operatorclient.ClientInterface { 73 return ctx.kubeClient 74 } 75 76 func (ctx TestContext) OperatorClient() versioned.Interface { 77 return ctx.operatorClient 78 } 79 80 func (ctx TestContext) DynamicClient() dynamic.Interface { 81 return ctx.dynamicClient 82 } 83 84 func (ctx TestContext) PackageClient() pversioned.Interface { 85 return ctx.packageClient 86 } 87 88 func (ctx TestContext) Client() k8scontrollerclient.Client { 89 return ctx.client 90 } 91 92 func (ctx TestContext) SSAClient() *controllerclient.ServerSideApplier { 93 return ctx.ssaClient 94 } 95 96 func (ctx TestContext) E2EClient() *util.E2EKubeClient { 97 return ctx.e2eClient 98 } 99 100 func (ctx TestContext) NewE2EClientSession() { 101 if ctx.e2eClient != nil { 102 _ = ctx.e2eClient.Reset() 103 } 104 ctx.e2eClient = util.NewK8sResourceManager(ctx.Client()) 105 } 106 107 func (ctx TestContext) DumpNamespaceArtifacts(namespace string) error { 108 if ctx.artifactsDir == "" { 109 ctx.Logf("$ARTIFACT_DIR is unset -- not collecting failed test case logs") 110 return nil 111 } 112 ctx.Logf("collecting logs in the %s artifacts directory", ctx.artifactsDir) 113 114 logDir := filepath.Join(ctx.artifactsDir, namespace) 115 if err := os.MkdirAll(logDir, os.ModePerm); err != nil { 116 return err 117 } 118 kubeconfigPath := ctx.kubeconfigPath 119 if kubeconfigPath == "" { 120 ctx.Logf("unable to determine kubeconfig path so defaulting to the $KUBECONFIG value") 121 kubeconfigPath = os.Getenv("KUBECONFIG") 122 } 123 124 envvars := []string{ 125 "TEST_NAMESPACE=" + namespace, 126 "TEST_ARTIFACTS_DIR=" + logDir, 127 "KUBECONFIG=" + kubeconfigPath, 128 "KUBECTL=" + os.Getenv("KUBECTL"), 129 } 130 131 cmd := exec.Command(ctx.artifactsScriptPath) 132 cmd.Env = append(os.Environ(), envvars...) 133 cmd.Stdout = os.Stdout 134 cmd.Stderr = os.Stderr 135 if err := cmd.Run(); err != nil { 136 return err 137 } 138 139 return nil 140 } 141 142 func setDerivedFields(ctx *TestContext) error { 143 if ctx == nil { 144 return fmt.Errorf("nil test context") 145 } 146 147 if ctx.restConfig == nil { 148 return fmt.Errorf("nil RESTClient") 149 } 150 151 if ctx.artifactsDir == "" { 152 if artifactsDir := os.Getenv("ARTIFACT_DIR"); artifactsDir != "" { 153 ctx.artifactsDir = artifactsDir 154 } 155 } 156 if ctx.artifactsScriptPath == "" { 157 if scriptPath := os.Getenv("E2E_ARTIFACT_SCRIPT"); scriptPath != "" { 158 ctx.artifactsScriptPath = scriptPath 159 } 160 } 161 162 kubeClient, err := operatorclient.NewClientFromRestConfig(ctx.restConfig) 163 if err != nil { 164 return err 165 } 166 ctx.kubeClient = kubeClient 167 168 operatorClient, err := versioned.NewForConfig(ctx.restConfig) 169 if err != nil { 170 return err 171 } 172 ctx.operatorClient = operatorClient 173 174 dynamicClient, err := dynamic.NewForConfig(ctx.restConfig) 175 if err != nil { 176 return err 177 } 178 ctx.dynamicClient = dynamicClient 179 180 packageClient, err := pversioned.NewForConfig(ctx.restConfig) 181 if err != nil { 182 return err 183 } 184 ctx.packageClient = packageClient 185 186 ctx.scheme = runtime.NewScheme() 187 localSchemeBuilder := runtime.NewSchemeBuilder( 188 apiextensionsv1.AddToScheme, 189 kscheme.AddToScheme, 190 operatorsv1alpha1.AddToScheme, 191 operatorsv1.AddToScheme, 192 operatorsv2.AddToScheme, 193 apiextensionsv1.AddToScheme, 194 appsv1.AddToScheme, 195 apiregistrationv1.AddToScheme, 196 ) 197 if err := localSchemeBuilder.AddToScheme(ctx.scheme); err != nil { 198 return err 199 } 200 201 client, err := k8scontrollerclient.New(ctx.restConfig, k8scontrollerclient.Options{ 202 Scheme: ctx.scheme, 203 }) 204 if err != nil { 205 return err 206 } 207 ctx.e2eClient = util.NewK8sResourceManager(client) 208 ctx.client = ctx.e2eClient 209 210 ctx.ssaClient, err = controllerclient.NewForConfig(ctx.restConfig, ctx.scheme, "test.olm.registry") 211 if err != nil { 212 return err 213 } 214 215 return nil 216 }