Skip to content

Commit

Permalink
refactor Apply-type functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mihaialexandrescu committed Aug 31, 2023
1 parent fefd7cb commit 7fab7ce
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 113 deletions.
3 changes: 2 additions & 1 deletion tests/e2e/install_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func requireCreatingKafkaCluster(kubectlOptions k8s.KubectlOptions, manifestPath
By(fmt.Sprintf("KafkaCluster %s already exists\n", kafkaClusterName))
} else {
By("Deploying a KafkaCluster")
applyK8sResourceManifest(kubectlOptions, manifestPath)
err := applyK8sResourceManifest(kubectlOptions, manifestPath)
Expect(err).NotTo(HaveOccurred())
}

By("Verifying the KafkaCluster state")
Expand Down
84 changes: 54 additions & 30 deletions tests/e2e/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,62 @@ import (
const (
// allowedCRDByteCount is the limitation of the number of bytes a CRD is
// allowed to have when being applied by K8s API server/kubectl.
allowedCRDByteCount = 262144 //nolint:unused // Note: this const is currently only used in helper functions which are not yet called on so this linter transitively fails for this const
allowedCRDByteCount = 262144 //nolint:unused // Note: this const is currently only used in helper functions which are not yet called on so this linter transitively fails for this const.

// crdNamePrefix is the prefix of the CRD names when listed through kubectl.
crdNamePrefix = "customresourcedefinition.apiextensions.k8s.io/" //nolint:unused // Note: this const is currently only used in helper functions which are not yet called on so this linter transitively fails for this const
crdNamePrefix = "customresourcedefinition.apiextensions.k8s.io/" //nolint:unused // Note: this const is currently only used in helper functions which are not yet called on so this linter transitively fails for this const.

// Per the kubectl spec, "dry-run" strategy must be "none", "server", or "client".
// With current use cases in e2e tests, we only expect to use "server" so the other options are commented out.
dryRunStrategyArgServer string = "--dry-run=server" // submit server-side request without persisting the resource.
//dryRunStrategyArgClient string = "--dry-run=client" // the resource is only validated locally but not sent to the Api-server.
//dryRunStrategyArgNone string = "--dry-run=none" // default value; submit server-side request and persist the resource.

)

// applyK8sResourceManifests applies the specified manifest to the provided
// kubectl context and namespace.
func applyK8sResourceManifest(kubectlOptions k8s.KubectlOptions, manifestPath string) { //nolint:unused // Note: this might come in handy for manual K8s resource operations.
By(fmt.Sprintf("Applying k8s manifest %s", manifestPath))
k8s.KubectlApply(GinkgoT(), &kubectlOptions, manifestPath)
func applyK8sResourceManifest(kubectlOptions k8s.KubectlOptions, manifestPath string, extraArgs ...string) error { //nolint:unused // Note: this might come in handy for manual K8s resource operations.
args := []string{"apply", "-f", manifestPath}
logMsg := fmt.Sprintf("Applying k8s manifest from path %s", manifestPath)
logMsg, args = kubectlArgExtender(args, logMsg, "", "", kubectlOptions.Namespace, extraArgs)
By(logMsg)

return k8s.RunKubectlE(GinkgoT(), &kubectlOptions, args...)
}

// applyK8sResourceManifestFromString applies the specified manifest in string format to the provided
// kubectl context and namespace.
func applyK8sResourceManifestFromString(kubectlOptions k8s.KubectlOptions, manifest string, extraArgs ...string) error {
// Replicating terratest's k8s.KubectlApplyFromStringE but with the possibility of a variadic argument that allows options like --dry-run
//
// TODO: look for a different implementation for temp files because terratest's version uses the composite test name to generate
// the temp file name which, in our case, includes all the descriptive Ginkgo statements (which are by design quite verbose).
// That can lead to erroring out on temp file creation based on the file name being too long.
tmpfile, err := k8s.StoreConfigToTempFileE(GinkgoT(), manifest)
if err != nil {
return err
}
defer os.Remove(tmpfile)

return applyK8sResourceManifest(kubectlOptions, tmpfile, extraArgs...)
}

// applyK8sResourceFromTemplate generates manifest from the specified go-template based on values
// and applies the specified manifest to the provided kubectl context and namespace.
func applyK8sResourceFromTemplate(kubectlOptions k8s.KubectlOptions, templateFile string, values map[string]interface{}, extraArgs ...string) error {
By(fmt.Sprintf("Generating k8s manifest from template %s", templateFile))
var manifest bytes.Buffer
rawTemplate, err := os.ReadFile(templateFile)
if err != nil {
return err
}
t := template.Must(template.New("template").Funcs(sprig.TxtFuncMap()).Parse(string(rawTemplate)))
err = t.Execute(&manifest, values)
if err != nil {
return err
}
return applyK8sResourceManifestFromString(kubectlOptions, manifest.String(), extraArgs...)
}

// isExistingK8SResource queries a Resource by it's kind, namespace and name and
Expand Down Expand Up @@ -191,7 +236,10 @@ func installK8sCRD(kubectlOptions k8s.KubectlOptions, crd []byte, shouldBeValida

createOrReplaceK8sResourcesFromManifest(kubectlOptions, "crd", object.GetName(), tempPath, shouldBeValidated)
default: // Note: regular CRD.
applyK8sResourceManifest(kubectlOptions, tempPath)
err = applyK8sResourceManifest(kubectlOptions, tempPath)
if err != nil {
return errors.WrapIfWithDetails(err, "applying CRD failed", "crd", string(crd))
}
}

return nil
Expand Down Expand Up @@ -453,30 +501,6 @@ func deleteK8sResourceNoErrNotFound(kubectlOptions k8s.KubectlOptions, timeout t
return err
}

// applyK8sResourceManifestFromString applies the specified manifest in string format to the provided
// kubectl context and namespace.
func applyK8sResourceManifestFromString(kubectlOptions k8s.KubectlOptions, manifest string) error {
By(fmt.Sprintf("Applying k8s manifest\n%s", manifest))
return k8s.KubectlApplyFromStringE(GinkgoT(), &kubectlOptions, manifest)
}

// applyK8sResourceFromTemplate generates manifest from the specified go-template based on values
// and applies the specified manifest to the provided kubectl context and namespace.
func applyK8sResourceFromTemplate(kubectlOptions k8s.KubectlOptions, templateFile string, values map[string]interface{}) error {
By(fmt.Sprintf("Generating K8s manifest from template %s", templateFile))
var manifest bytes.Buffer
rawTemplate, err := os.ReadFile(templateFile)
if err != nil {
return err
}
t := template.Must(template.New("template").Funcs(sprig.TxtFuncMap()).Parse(string(rawTemplate)))
err = t.Execute(&manifest, values)
if err != nil {
return err
}
return applyK8sResourceManifestFromString(kubectlOptions, manifest.String())
}

// listK8sResourceKinds lists all of the available resource kinds on the K8s cluster
// with the apiGroupSelector parameter the result can be narrowed by the resource group.
// extraArgs can be any kubectl api-resources parameter.
Expand Down
Loading

0 comments on commit 7fab7ce

Please sign in to comment.