Skip to content

Commit

Permalink
Use envsubst to templatize deployment yaml
Browse files Browse the repository at this point in the history
Signed-off-by: Kyle Squizzato <[email protected]>
  • Loading branch information
squizzi committed Aug 23, 2024
1 parent 6ae1adc commit 1bd2311
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 63 deletions.
6 changes: 3 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ issues:
# restore some of the defaults
# (fill in the rest as needed)
exclude-rules:
- path: "api/*"
- path: 'api/*'
linters:
- lll
- path: "internal/*"
- path: 'internal/*'
linters:
- dupl
- lll
Expand All @@ -21,7 +21,7 @@ linters:
enable:
- dupl
- errcheck
- exportloopref
- copyloopvar
- goconst
- gocyclo
- gofmt
Expand Down
26 changes: 13 additions & 13 deletions config/dev/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
apiVersion: hmc.mirantis.com/v1alpha1
kind: Deployment
metadata:
name: bba1743d-e2e-test
name: aws-dev
spec:
config:
controlPlane:
amiID: ami-0989c067ff3da4b27
instanceType: t3.small
controlPlaneNumber: 1
publicIP: true
region: us-west-2
worker:
amiID: ami-0989c067ff3da4b27
instanceType: t3.small
workersNumber: 1
template: aws-standalone-cp
template: aws-standalone-cp
config:
region: us-east-2
publicIP: true
controlPlaneNumber: 1
workersNumber: 1
controlPlane:
amiID: ami-02f3416038bdb17fb
instanceType: t3.small
worker:
amiID: ami-02f3416038bdb17fb
instanceType: t3.small
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/Mirantis/hmc
go 1.22.0

require (
github.com/a8m/envsubst v1.4.2
github.com/cert-manager/cert-manager v1.15.3
github.com/fluxcd/helm-controller/api v1.0.1
github.com/fluxcd/pkg/apis/meta v1.6.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg=
github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
Expand Down
40 changes: 11 additions & 29 deletions test/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os/exec"

"github.com/Mirantis/hmc/test/utils"
"github.com/a8m/envsubst"
"github.com/google/uuid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -43,7 +44,7 @@ const (
)

//go:embed resources/deployment.yaml.tpl
var deploymentConfigBytes []byte
var deploymentTemplateBytes []byte

// GetUnstructuredDeployment returns an unstructured deployment object based on
// the provider and template.
Expand All @@ -53,41 +54,22 @@ func GetUnstructuredDeployment(provider ProviderType, templateName Template) *un
generatedName := uuid.New().String()[:8] + "-e2e-test"
_, _ = fmt.Fprintf(GinkgoWriter, "Generated AWS cluster name: %q\n", generatedName)

var deploymentConfig map[string]interface{}

err := yaml.Unmarshal(deploymentConfigBytes, &deploymentConfig)
Expect(err).NotTo(HaveOccurred(), "failed to unmarshal deployment config")

switch provider {
case ProviderAWS:
// XXX: Maybe we should just use automatic AMI selection here.
amiID := getAWSAMI()
awsRegion := os.Getenv("AWS_REGION")

// Modify the deployment config to use the generated name and the AMI.
// TODO: This should be modified to use go templating.
if metadata, ok := deploymentConfig["metadata"].(map[string]interface{}); ok {
metadata["name"] = generatedName
} else {
// Ensure we always have a metadata.name field populated.
deploymentConfig["metadata"] = map[string]interface{}{"name": generatedName}
}

if spec, ok := deploymentConfig["spec"].(map[string]interface{}); ok {
if config, ok := spec["config"].(map[string]interface{}); ok {
if awsRegion != "" {
config["region"] = awsRegion
}
Expect(os.Setenv("AMI_ID", amiID)).NotTo(HaveOccurred())
Expect(os.Setenv("DEPLOYMENT_NAME", generatedName)).NotTo(HaveOccurred())
Expect(os.Setenv("TEMPLATE_NAME", string(templateName))).NotTo(HaveOccurred())

if worker, ok := config["worker"].(map[string]interface{}); ok {
worker["amiID"] = amiID
}
deploymentConfigBytes, err := envsubst.Bytes(deploymentTemplateBytes)
Expect(err).NotTo(HaveOccurred(), "failed to substitute environment variables")

if controlPlane, ok := config["controlPlane"].(map[string]interface{}); ok {
controlPlane["amiID"] = amiID
}
}
}
var deploymentConfig map[string]interface{}

err = yaml.Unmarshal(deploymentConfigBytes, &deploymentConfig)
Expect(err).NotTo(HaveOccurred(), "failed to unmarshal deployment config")

return &unstructured.Unstructured{Object: deploymentConfig}
default:
Expand Down
15 changes: 8 additions & 7 deletions test/deployment/resources/deployment.yaml.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ kind: Deployment
metadata:
name: ${DEPLOYMENT_NAME}
spec:
template: ${TEMPLATE_NAME}
config:
region: ${AWS_REGION}
publicIP: ${PUBLIC_IP:=true}
controlPlaneNumber: ${CONTROL_PLANE_NUMBER:=1}
workersNumber: ${WORKERS_NUMBER:=1}
controlPlane:
amiID: ${AMI_ID}
instanceType: ${INSTANCE_TYPE}
controlPlaneNumber: ${CONTROL_PLANE_NUMBER}
publicIP: ${PUBLIC_IP}
region: ${AWS_REGION}
instanceType: ${INSTANCE_TYPE:=t3.small}
worker:
amiID: ${AMI_ID}
instanceType: ${INSTANCE_TYPE}
workersNumber: ${WORKERS_NUMBER}
template: ${TEMPLATE_NAME}
instanceType: ${INSTANCE_TYPE:=t3.small}

2 changes: 1 addition & 1 deletion test/deployment/validate_deleted.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func VerifyProviderDeleted(ctx context.Context, kc *kubeclient.KubeClient, clust
// as to not move on to the next resource type until the first is resolved.
// We use []string here since order is important.
for _, name := range []string{"control-planes", "machinedeployments", "clusters"} {
validator, ok := resourceValidators[name]
validator, ok := deletionValidators[name]
if !ok {
continue
}
Expand Down
5 changes: 2 additions & 3 deletions test/deployment/validate_deployed.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ func validateCSIDriver(ctx context.Context, kc *kubeclient.KubeClient, clusterNa
// Since these resourceValidationFuncs are intended to be used in
// Eventually we should ensure a follow-up PVCreate is a no-op.
if !apierrors.IsAlreadyExists(err) {
// XXX: Maybe we should Fail here?
return fmt.Errorf("failed to create test PVC: %w", err)
Fail(fmt.Sprintf("failed to create test PVC: %v", err))
}
}

Expand Down Expand Up @@ -228,7 +227,7 @@ func validateCSIDriver(ctx context.Context, kc *kubeclient.KubeClient, clusterNa
}, metav1.CreateOptions{})
if err != nil {
if !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("failed to create test Pod: %w", err)
Fail(fmt.Sprintf("failed to create test Pod: %v", err))
}
}

Expand Down
6 changes: 3 additions & 3 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var _ = Describe("controller", Ordered, func() {
}

if len(podList.Items) != 1 {
return fmt.Errorf("expected 1 controller pod, got %d", len(podList.Items))
return fmt.Errorf("expected 1 cluster-api-controller pod, got %d", len(podList.Items))
}

controllerPod := podList.Items[0]
Expand All @@ -84,15 +84,15 @@ var _ = Describe("controller", Ordered, func() {

return nil
}
EventuallyWithOffset(1, func() error {
Eventually(func() error {
err := verifyControllerUp()
if err != nil {
_, _ = fmt.Fprintf(GinkgoWriter, "Controller pod validation failed: %v\n", err)
return err
}

return nil
}(), 5*time.Minute, time.Second).Should(Succeed())
}).WithTimeout(5 * time.Minute).WithPolling(10 * time.Second).Should(Succeed())
})
})

Expand Down
2 changes: 1 addition & 1 deletion test/kubeclient/kubeclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (kc *KubeClient) ListMachineDeployments(
func (kc *KubeClient) ListK0sControlPlanes(
ctx context.Context, clusterName string) ([]unstructured.Unstructured, error) {
return kc.listResource(ctx, schema.GroupVersionResource{
Group: "control-plane.cluster.x-k8s.io",
Group: "controlplane.cluster.x-k8s.io",
Version: "v1beta1",
Resource: "k0scontrolplanes",
}, clusterName)
Expand Down
6 changes: 3 additions & 3 deletions test/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,16 @@ func ValidateConditionsTrue(unstrObj *unstructured.Unstructured) error {
continue
}

errorStr := fmt.Sprintf("%s: %s", c.Type, c.Reason)
errorStr := fmt.Sprintf("%s - Reason: %s", c.Type, c.Reason)
if c.Message != "" {
errorStr = fmt.Sprintf("%s: %s", errorStr, c.Message)
}

errs = errors.Join(fmt.Errorf(errorStr), errs)
errs = errors.Join(errors.New(errorStr), errs)
}

if errs != nil {
return fmt.Errorf("%s %s is not ready with conditions: %w", objKind, objName, errs)
return fmt.Errorf("%s %s is not ready with conditions:\n%w", objKind, objName, errs)
}

return nil
Expand Down

0 comments on commit 1bd2311

Please sign in to comment.