From 707a3d5ba7fe00238b3543e03fe4556420fb7cc2 Mon Sep 17 00:00:00 2001 From: sheldonhull Date: Tue, 24 Jan 2023 19:29:03 -0600 Subject: [PATCH] fix: resolve incorrect binary path for docker hub based images (#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes #83 reported by @JulianPedro 👍 - Development tooling tweaks to work on addressing some timeouts in devcontainers. This isn't confirmed resolved as not sure if vscode configuration issue, codespaces issue, or something else causing this. Local development works fine, but container based workspaces seem to have timeouts randomly. - Create a new dockerhub release. - fixes [AB#483421](https://thycotic.visualstudio.com/4a89362e-1361-424f-a291-a8f57c2a8991/_workitems/edit/483421) #83 --- ...237\224\250 Refactor-20230104-191219.yaml" | 10 -- ...\244\226 Development-20230104-184442.yaml" | 9 -- .devcontainer/Dockerfile | 2 + .devcontainer/devcontainer.json | 13 +- .envrc | 2 + .trunk/actions | 2 +- .trunk/notifications | 2 +- .trunk/trunk.yaml | 14 +- CHANGELOG.md | 23 +++ aqua.yaml | 2 + charts/dsv-injector/Chart.yaml | 2 +- charts/dsv-injector/README.md | 7 +- charts/dsv-injector/templates/deployment.yaml | 2 +- charts/dsv-injector/values.yaml | 2 + charts/dsv-syncer/Chart.yaml | 2 +- charts/dsv-syncer/README.md | 7 +- .../dsv-syncer/templates/syncer-cronjob.yaml | 2 +- charts/dsv-syncer/values.yaml | 2 + docker/Dockerfile.distroless | 5 +- magefiles/constants/constants.mage.go | 2 + magefiles/constants/variables.mage.go | 6 +- magefiles/jobs.mage.go | 8 +- magefiles/kind/kind.mage.go | 4 +- magefiles/magefile.go | 3 +- magefiles/minikube/minikube.mage.go | 132 ++++++++++++++++++ 25 files changed, 217 insertions(+), 48 deletions(-) delete mode 100644 ".changes/unreleased/\360\237\224\250 Refactor-20230104-191219.yaml" delete mode 100644 ".changes/unreleased/\360\237\244\226 Development-20230104-184442.yaml" create mode 100644 magefiles/minikube/minikube.mage.go diff --git "a/.changes/unreleased/\360\237\224\250 Refactor-20230104-191219.yaml" "b/.changes/unreleased/\360\237\224\250 Refactor-20230104-191219.yaml" deleted file mode 100644 index dffd9e9..0000000 --- "a/.changes/unreleased/\360\237\224\250 Refactor-20230104-191219.yaml" +++ /dev/null @@ -1,10 +0,0 @@ -kind: "\U0001F528 Refactor" -body: Point the helm charts towards docker hub based images, instead of quay, as these - are now iterated on with changelog driven release instead of each commit. This should - reduce frequency of needless version updates. -time: 2023-01-04T19:12:19.782728-06:00 -custom: - azure-boards-workitemid-fixed: "" - azure-boards-workitemid-related: "" - github-contributor: sheldonhull - github-link: "" diff --git "a/.changes/unreleased/\360\237\244\226 Development-20230104-184442.yaml" "b/.changes/unreleased/\360\237\244\226 Development-20230104-184442.yaml" deleted file mode 100644 index d028208..0000000 --- "a/.changes/unreleased/\360\237\244\226 Development-20230104-184442.yaml" +++ /dev/null @@ -1,9 +0,0 @@ -kind: "\U0001F916 Development" -body: Bump aqua tooling and include dsv-cli in the project setup. Include `CGO_ENABLED=0` - to avoid issues with running commands in devcontainers & codespaces. -time: 2023-01-04T18:44:42.354056-06:00 -custom: - azure-boards-workitemid-fixed: "" - azure-boards-workitemid-related: "" - github-contributor: sheldonhull - github-link: "" diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index fedce38..4480bc9 100755 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,6 +6,8 @@ ARG GOPATH USER root ENV DOCKER_BUILDKIT=1 ENV GOPATH=$GOPATH +# to avoid gcc compile issues as don't need gcc except for race conditions testing +ENV CGO_ENABLED=0 ENV MAGEFILE_ENABLE_COLOR=1 ENV TRUNK_LAUNCHER_QUIET=true ENV PATH="$GOPATH/bin:/home/$DEVCONTAINER_USER/.local/share/aquaproj-aqua/bin:/home/$DEVCONTAINER_USER/go/bin:$PATH" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 42c4d09..1bbe085 100755 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,6 +25,8 @@ "source=${localEnv:HOME}${localEnv:USERPROFILE}/.kube,target=/home/vscode/.kube/,type=bind,consistency=cached", // support for SSH keys "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/vscode/.ssh/,type=bind,consistency=cached", // support for SSH keys "source=${localEnv:HOME}${localEnv:USERPROFILE}/.envrc,target=/home/vscode/.envrc,type=bind,consistency=cached", // envrc from home to allow direnv to mount credentials + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.thy,target=/home/vscode/.thy/,type=bind,consistency=cached", // support for dsv-cli filestore based store + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.dsv.yml,target=/home/vscode/.dsv.yml/,type=bind,consistency=cached", // mounting for dsv-config // cache gopath directory "source=go-path,target=/home/vscode/go/,type=volume" ], @@ -61,12 +63,15 @@ // Use 'postCreateCommand' to run commands after the container is created. // "postCreateCommand": "", // Use 'postStartCommand' to run commands after the container is created like starting minikube. - "postStartCommand": "sudo chown -R vscode /home/vscode/go/ && export GOPATH=/home/vscode/go/ && echo '🔨 aqua tooling download' && aqua install && echo '✅ aqua install complete' && echo '🔨 running go mod download' && /home/vscode/.local/share/aquaproj-aqua/bin/go mod download && echo '✅ go mod download finished' && echo '🔨 downloading build tooling dependencies' && /home/vscode/.local/share/aquaproj-aqua/bin/mage && echo '✅ build tooling dependencies complete'", + "postStartCommand": "sudo chown -R vscode /home/vscode/go/ && export GOPATH=/home/vscode/go/ && echo '🔨 aqua tooling download' && aqua install && echo '✅ aqua install complete' && echo +'🔨 running go mod download' && /home/vscode/.local/share/aquaproj-aqua/bin/go mod download && echo '✅ go mod download finished' && echo '🔨 downloading build tooling dependencies' && +/home/vscode/.local/share/aquaproj-aqua/bin/mage -compile ./magec && echo '✅ build tooling dependencies complete'", // Minikube does not like running as root, so use a non-root user. "remoteUser": "vscode", "containerEnv": { "ENABLE_NONROOT_DOCKER": "true", - "GITHUB_OATH_TOKEN": "${localEnv:GITHUB_OATH_TOKEN}" + "GITHUB_OATH_TOKEN": "${localEnv:GITHUB_OATH_TOKEN}", + "CGO_ENABLED": "false", }, "remoteEnv": { "ENABLE_NONROOT_DOCKER": "true" @@ -85,10 +90,10 @@ "username": "vscode", "installOhMyZsh": true }, - "ghcr.io/devcontainers/features/docker-in-docker:1.0.7": { + "ghcr.io/devcontainers/features/docker-in-docker:2": { "version": "latest", "dockerDashComposeVersion": "v2", "username": "vscode" } } -} +} \ No newline at end of file diff --git a/.envrc b/.envrc index ea697db..fce6102 100644 --- a/.envrc +++ b/.envrc @@ -1,3 +1,4 @@ +export PATH="${AQUA_ROOT_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/aquaproj-aqua}/bin:$PATH" # for those using aqua this will ensure it's in the path with all tools if loading from home export DIRENV_WARN_TIMEOUT='10s' export DIRENV_LOG_FORMAT="" @@ -14,3 +15,4 @@ export DSV_CREDENTIALS_ANNOTATION_VALUE='app1' export DSV_K8S_TEST_SECRET_PATH='k8s:sync:test' # Without this codespaces might have an issues with loading with mage initially without gcc being installed export CGO_ENABLED=0 +export MAGEFILE_HASHFAST=1 # use mage -f to force recompile, this should make it faster if you aren't editing magefiles often diff --git a/.trunk/actions b/.trunk/actions index eb4c194..a057bc2 120000 --- a/.trunk/actions +++ b/.trunk/actions @@ -1 +1 @@ -/home/vscode/.cache/trunk/repos/d04a383d1909a139617b5284ddf891a9/actions \ No newline at end of file +/Users/sheldon.hull/.cache/trunk/repos/f2d85cb9ef0af4dd9360d429942edea0/actions \ No newline at end of file diff --git a/.trunk/notifications b/.trunk/notifications index 3d7038d..b8cdc0b 120000 --- a/.trunk/notifications +++ b/.trunk/notifications @@ -1 +1 @@ -/home/vscode/.cache/trunk/repos/d04a383d1909a139617b5284ddf891a9/notifications \ No newline at end of file +/Users/sheldon.hull/.cache/trunk/repos/f2d85cb9ef0af4dd9360d429942edea0/notifications \ No newline at end of file diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index d066bda..6adaccc 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -2,7 +2,7 @@ version: 0.1 plugins: sources: - id: trunk - ref: v0.0.5 + ref: v0.0.8 uri: https://github.com/trunk-io/plugins actions: enabled: @@ -44,16 +44,18 @@ runtimes: value: 1 enabled: [go@1.19, node@16.14.2, python@3.10.3] cli: - version: 1.3.1 + version: 1.3.2 lint: + disabled: + - cspell enabled: - - cspell@6.19.2 + #- cspell@6.19.2 + - prettier@2.3.0 - git-diff-check - - prettier@2.8.3 - taplo@0.7.0 - yamllint@1.29.0 - - actionlint@1.6.22 - - gitleaks@8.15.2 + - actionlint@1.6.23 + - gitleaks@8.15.3 - gofmt@1.19.3 - golangci-lint@1.50.1 - hadolint@2.12.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a8b2c..31d6096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v1.1.5 - 2023-01-24 + +### 🔨 Refactor + +- Point the helm charts towards docker hub based images, instead of quay, as these are now iterated on with changelog driven release instead of each commit. This should reduce frequency of needless version updates. + +### 🐛 Bug Fix + +- Docker Hub published images did not have the correct path to the injector and syncer, resulting in an invalid entrypoint. This is fixed and should now correctly resolve when using the updated helm charts that provide a qualified path. For example: `/app/dsv-injector` instead of just saying `dsv-injector` now. This is due to using a minimal distroless image and not copying binaries into a path that is assumed to be resolved automatically by `PATH`, such as `/usr/local/bin`. Now the path to the binary is explicitly set and should resolve any path resolution issues. + +### 🤖 Development + +- Bump aqua tooling and include dsv-cli in the project setup. Include `CGO_ENABLED=0` to avoid issues with running commands in devcontainers & codespaces. + +### Related + +- fixes AB#483421 +- [Issue 83 Fixed](https://github.com/DelineaXPM/dsv-k8s/issues/83). Thank you @JulianPedro for helping identify this and opening the descriptive issue. 👍 + +### Contributors + +- [sheldonhull](https://github.com/sheldonhull) + ## v1.1.4 - 2022-10-11 ### Security diff --git a/aqua.yaml b/aqua.yaml index e52297e..50946fc 100644 --- a/aqua.yaml +++ b/aqua.yaml @@ -22,3 +22,5 @@ packages: version: v1.25.2 - name: helm/helm@v3.10.3 - name: DelineaXPM/dsv-cli@v1.39.11 + - name: kubernetes/minikube@v1.28.0 + - name: stern/stern@v1.22.0 diff --git a/charts/dsv-injector/Chart.yaml b/charts/dsv-injector/Chart.yaml index 0c55052..dc56a99 100644 --- a/charts/dsv-injector/Chart.yaml +++ b/charts/dsv-injector/Chart.yaml @@ -9,7 +9,7 @@ keywords: - secrets - vault type: application -version: 0.2.2 +version: 0.2.3 appVersion: latest maintainers: - name: Sheldon Hull diff --git a/charts/dsv-injector/README.md b/charts/dsv-injector/README.md index 2a29b3c..bd4de10 100644 --- a/charts/dsv-injector/README.md +++ b/charts/dsv-injector/README.md @@ -1,6 +1,6 @@ # dsv-injector -![Version: 0.2.2](https://img.shields.io/badge/Version-0.2.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) +![Version: 0.2.3](https://img.shields.io/badge/Version-0.2.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) A Helm chart for the Delinea DevOps Secrets Vault (DSV) Injector Mutating Webhook. @@ -18,6 +18,7 @@ A Helm chart for the Delinea DevOps Secrets Vault (DSV) Injector Mutating Webhoo | containerPort | int | `18543` | containerPort is the port that the container itself listens on | | credentialsJson | string | `"{\n \"default\": {\n \"credentials\": {\n \"clientId\": \"\",\n \"clientSecret\": \"\"\n },\n \"tenant\": \"example\"\n }\n}"` | credentialsJson contains the JSON-formatted credentials file (see README.md) @default - placeholder. _REQUIRED FIELD_ | | fullnameOverride | string | `""` | | +| image.entrypoint | string | `"/app/dsv-injector"` | Entrypoint is the path to the binary. Since the container image could contain multiple binaries, this makes sure it's correctly mapped to the binary. | | image.pullPolicy | string | `"Always"` | | | image.repository | string | `"docker.io/delineaxpm/dsv-k8s"` | | | image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | @@ -33,3 +34,7 @@ A Helm chart for the Delinea DevOps Secrets Vault (DSV) Injector Mutating Webhoo | webhookPort | int | 8543 | webhookPort is the port that the webhook endpoint is listening on | | webhookScope | string | "Namespaced" | webhookScope specifies which resources are in scope, "Cluster", "Namespaced" or "\*" | | webhookUri | string | `"/inject"` | webhookUri is path portion of the URL of the webhook endpoint | + +--- + +Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/charts/dsv-injector/templates/deployment.yaml b/charts/dsv-injector/templates/deployment.yaml index 25c9419..96cb8ac 100644 --- a/charts/dsv-injector/templates/deployment.yaml +++ b/charts/dsv-injector/templates/deployment.yaml @@ -26,7 +26,7 @@ spec: {{- end }} containers: - name: {{ .Chart.Name }} - command: [{{ include "dsv.name" . }}] + command: [{{ .Values.image.entrypoint }}] securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" diff --git a/charts/dsv-injector/values.yaml b/charts/dsv-injector/values.yaml index 4557d82..3a7ca28 100644 --- a/charts/dsv-injector/values.yaml +++ b/charts/dsv-injector/values.yaml @@ -24,6 +24,8 @@ image: pullPolicy: Always # -- Overrides the image tag whose default is the chart appVersion. tag: '' + # -- Entrypoint is the path to the binary. Since the container image could contain multiple binaries, this makes sure it's correctly mapped to the binary. + entrypoint: /app/dsv-injector imagePullSecrets: [] nameOverride: '' diff --git a/charts/dsv-syncer/Chart.yaml b/charts/dsv-syncer/Chart.yaml index eff0dbb..86593a5 100644 --- a/charts/dsv-syncer/Chart.yaml +++ b/charts/dsv-syncer/Chart.yaml @@ -9,7 +9,7 @@ keywords: - secrets - vault type: application -version: 0.1.2 +version: 0.1.3 appVersion: latest maintainers: - name: Sheldon Hull diff --git a/charts/dsv-syncer/README.md b/charts/dsv-syncer/README.md index 8b06f8f..b453e7c 100644 --- a/charts/dsv-syncer/README.md +++ b/charts/dsv-syncer/README.md @@ -1,6 +1,6 @@ # dsv-syncer -![Version: 0.1.2](https://img.shields.io/badge/Version-0.1.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) +![Version: 0.1.3](https://img.shields.io/badge/Version-0.1.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: latest](https://img.shields.io/badge/AppVersion-latest-informational?style=flat-square) A Helm chart for the Delinea DevOps Secrets Vault (DSV) Kubernetes Synchronizer Job. @@ -18,6 +18,7 @@ A Helm chart for the Delinea DevOps Secrets Vault (DSV) Kubernetes Synchronizer | cronJobSchedule | string | `"* * * * *"` | cronJobSchedule controls when the syncer runs; five asterisks means "every minute". See [cronjob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax) @default - every minute, ie '\* \* \* \* \*' | | dsvInjectorCredentialsSecretName | string | `"dsv-injector-credentials"` | dsvInjectorCredentialsSecretName is the name of thecredentialsJson secret from the dsv-injector | | fullnameOverride | string | `""` | | +| image.entrypoint | string | `"/app/dsv-syncer"` | Entrypoint is the path to the binary. Since the container image could contain multiple binaries, this makes sure it's correctly mapped to the binary. | | image.pullPolicy | string | `"Always"` | | | image.repository | string | `"docker.io/delineaxpm/dsv-k8s"` | | | image.tag | string | `""` | | @@ -31,3 +32,7 @@ A Helm chart for the Delinea DevOps Secrets Vault (DSV) Kubernetes Synchronizer | serviceAccount.annotations | object | `{}` | Annotations to add to the service account @default - Adds `dsv-filter-name` to simplify log selector streaming | | serviceAccount.create | bool | `true` | Specifies whether a service account should be created @default - true | | serviceAccount.name | string | `""` | If not set and create is true, a name is generated using the fullname template | + +--- + +Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/charts/dsv-syncer/templates/syncer-cronjob.yaml b/charts/dsv-syncer/templates/syncer-cronjob.yaml index 316ac5c..cfddadf 100644 --- a/charts/dsv-syncer/templates/syncer-cronjob.yaml +++ b/charts/dsv-syncer/templates/syncer-cronjob.yaml @@ -19,7 +19,7 @@ spec: spec: containers: - name: {{ .Chart.Name }} - command: [{{ include "dsv.name" . }}] + command: [{{ .Values.image.entrypoint }}] resources: {{- toYaml .Values.resources | nindent 14 }} securityContext: diff --git a/charts/dsv-syncer/values.yaml b/charts/dsv-syncer/values.yaml index b3aae52..8b47caa 100644 --- a/charts/dsv-syncer/values.yaml +++ b/charts/dsv-syncer/values.yaml @@ -13,6 +13,8 @@ image: pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. tag: '' + # -- Entrypoint is the path to the binary. Since the container image could contain multiple binaries, this makes sure it's correctly mapped to the binary. + entrypoint: /app/dsv-syncer imagePullSecrets: [] nameOverride: '' diff --git a/docker/Dockerfile.distroless b/docker/Dockerfile.distroless index d4899c0..c58a01c 100644 --- a/docker/Dockerfile.distroless +++ b/docker/Dockerfile.distroless @@ -26,8 +26,9 @@ # move back to nonroot when done. # nonroot won't work for github actions # https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#user this was for dockerfile approach, not docker image but it worked well this way. -# trunk-ignore(hadolint/DL3007) + + +# If you change the copy location, you'll want to make sure to change the path in the helm charts and publish a new version. FROM gcr.io/distroless/static:nonroot COPY dsv-syncer /app/dsv-syncer COPY dsv-injector /app/dsv-injector - diff --git a/magefiles/constants/constants.mage.go b/magefiles/constants/constants.mage.go index ecf6a11..4639db3 100644 --- a/magefiles/constants/constants.mage.go +++ b/magefiles/constants/constants.mage.go @@ -36,4 +36,6 @@ const ( // ChartsDirectory is the directory where the helm charts are placed, in sub directories. ChartsDirectory = "charts" + // DockerImageQualified is the qualified path of the image in Docker Hub. + DockerImageQualified = "docker.io/delineaxpm/dsv-k8s" ) diff --git a/magefiles/constants/variables.mage.go b/magefiles/constants/variables.mage.go index 7503f89..92b8d0e 100644 --- a/magefiles/constants/variables.mage.go +++ b/magefiles/constants/variables.mage.go @@ -14,7 +14,7 @@ type HelmCharts struct { Values string } -var HelmChartsList = []HelmCharts{ //nolint:gochecknoglobals // Integration testing global variable is fine to leave. +var HelmChartsList = []HelmCharts{ { ReleaseName: "dsv-syncer", ChartPath: "./charts/dsv-syncer", @@ -30,8 +30,8 @@ var HelmChartsList = []HelmCharts{ //nolint:gochecknoglobals // Integration test } // DefaultHelmTimeoutMinutes is the default timeout for helm commands. -var DefaultHelmTimeoutMinutes = time.Minute * 5 //nolint:gochecknoglobals // Integration testing global variable is fine to leave. +var DefaultHelmTimeoutMinutes = time.Minute * 5 // CacheManifestDirectory is the directory where helm charts are cached for local tweaking. // They are copied from the examples directory to allow editing without committing to source control. -var CacheManifestDirectory = filepath.Join(CacheDirectory, "manifests") //nolint:gochecknoglobals // Integration testing global variable is fine to leave. +var CacheManifestDirectory = filepath.Join(CacheDirectory, "manifests") diff --git a/magefiles/jobs.mage.go b/magefiles/jobs.mage.go index 19c0183..1b8a671 100644 --- a/magefiles/jobs.mage.go +++ b/magefiles/jobs.mage.go @@ -4,7 +4,8 @@ import ( "github.com/DelineaXPM/dsv-k8s/v2/magefiles/constants" "github.com/DelineaXPM/dsv-k8s/v2/magefiles/helm" "github.com/DelineaXPM/dsv-k8s/v2/magefiles/k8s" - "github.com/DelineaXPM/dsv-k8s/v2/magefiles/kind" + // "github.com/DelineaXPM/dsv-k8s/v2/magefiles/kind" + "github.com/DelineaXPM/dsv-k8s/v2/magefiles/minikube" "github.com/magefile/mage/mg" "github.com/pterm/pterm" ) @@ -18,7 +19,8 @@ type Job mg.Namespace func (Job) Init() { pterm.DefaultSection.Println("(Job) Init()") mg.SerialDeps( - kind.Kind{}.Init, + // kind.Kind{}.Init, + minikube.Minikube{}.Init, k8s.K8s{}.Init, helm.Helm{}.Init, ) @@ -28,7 +30,7 @@ func (Job) Init() { func (Job) Setup() { pterm.DefaultSection.Println("(Job) Setup()") mg.SerialDeps( - kind.Kind{}.Init, + minikube.Minikube{}.Init, k8s.K8s{}.Init, helm.Helm{}.Init, mg.F(k8s.K8s{}.Apply, constants.CacheManifestDirectory), diff --git a/magefiles/kind/kind.mage.go b/magefiles/kind/kind.mage.go index 949198d..51e20a9 100644 --- a/magefiles/kind/kind.mage.go +++ b/magefiles/kind/kind.mage.go @@ -116,11 +116,11 @@ func (Kind) Init() error { dspin.SuccessPrinter.Printfln("namespace created: %s", constants.KubectlNamespace) } dspin.UpdateText("pulling docker images") - if err := sh.Run("docker", "pull", "quay.io/delinea/dsv-k8s:latest"); err != nil { + if err := sh.Run("docker", "pull", constants.DockerImageQualified); err != nil { dspin.WarningPrinter.Printfln("docker pull: %v", err) return fmt.Errorf("docker pull: %w", err) } - dspin.SuccessPrinter.Println("docker image for quay.io/delinea/dsv-k8s:latest pulled") + dspin.SuccessPrinter.Println("docker image for " + constants.DockerImageQualified) // Not working right now, can't find nodes for Kind to preload. Not critical so commenting out for now - sheldon. // Sp.UpdateText("preloading docker image into kind cluster") // if err := sh.Run("kind", "load", "docker-image", "quay.io/delinea/dsv-k8s:latest"); err != nil { diff --git a/magefiles/magefile.go b/magefiles/magefile.go index 5c25b96..e95136a 100644 --- a/magefiles/magefile.go +++ b/magefiles/magefile.go @@ -13,7 +13,8 @@ import ( "github.com/DelineaXPM/dsv-k8s/v2/magefiles/k8s" // mage:import _ "github.com/DelineaXPM/dsv-k8s/v2/magefiles/kind" - + // mage:import + _ "github.com/DelineaXPM/dsv-k8s/v2/magefiles/minikube" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" "github.com/pterm/pterm" diff --git a/magefiles/minikube/minikube.mage.go b/magefiles/minikube/minikube.mage.go new file mode 100644 index 0000000..80a528b --- /dev/null +++ b/magefiles/minikube/minikube.mage.go @@ -0,0 +1,132 @@ +// Minikube package contains all the tasks for automation of kind cluster creation and tear down, and the required kubectl commands to correctly use this. +package minikube + +import ( + "fmt" + "os" + "time" + + "github.com/DelineaXPM/dsv-k8s/v2/magefiles/constants" + + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + "github.com/pterm/pterm" + mtu "github.com/sheldonhull/magetools/pkg/magetoolsutils" +) + +// Minikube contains the kind cli commands. +type Minikube mg.Namespace + +func createCluster() error { + mtu.CheckPtermDebug() + minikubeArgs := []string{ + "start", + "--profile", constants.KindClusterName, + "--namespace", constants.KubectlNamespace, + } + // if os.Getenv("KIND_SETUP_CONFIG") != "" { + // pterm.Info.Printfln("KIND_SETUP_CONFIG: %s", os.Getenv("KIND_SETUP_CONFIG")) + // minikubeArgs = append(minikubeArgs, "--config", os.Getenv("KIND_SETUP_CONFIG")) + // } + if err := sh.RunV( + "minikube", + minikubeArgs..., + ); err != nil { + return err + } + return nil +} + +func updateKubeconfig() error { + mtu.CheckPtermDebug() + if _, err := os.Stat(constants.Kubeconfig); os.IsNotExist(err) { + if _, err := os.Create(constants.Kubeconfig); err != nil { + pterm.Error.Printfln("unable to create empty placeholder file: %v", err) + } + } + _, err := sh.Output("minikube", "update-context", "--profile", constants.KindClusterName) + if err != nil { + pterm.Error.Println("unable to get minikube cluster info, maybe you need to run mage minikube:init first?") + return err + } + + // if err := os.WriteFile(constants.Kubeconfig, []byte(kc), constants.PermissionUserReadWriteExecute); err != nil { + // pterm.Error.Printfln("unable to write kubeconfig to file: %v", err) + // return err + // } + pterm.Info.Printfln("kubeconfig updated: %s", constants.Kubeconfig) + // for now this is only going to be run against Kind cluster. + // if err := sh.Run( + // "kubectl", + // "cluster-info", "--context", constants.KindContextName, + // "--cluster", constants.KindContextName, + // ); err != nil { + // return err + // } + return nil +} + +// ➕ Create creates a new Minikube cluster and populates a kubeconfig in cachedirectory. +func (Minikube) Init() error { + mtu.CheckPtermDebug() + if err := createCluster(); err != nil { + return err + } + dspin, _ := pterm.DefaultSpinner. + WithDelay(time.Second). + WithRemoveWhenDone(true). + WithShowTimer(true). + WithText("Init()\n"). + WithSequence("|", "/", "-", "|", "/", "-", "\\").Start() + dspin.SuccessPrinter.Println("ensuring it's in kubeconfig") + if err := updateKubeconfig(); err != nil { + pterm.Error.Printfln("updateKubeconfig(): %v", err) + } + dspin.UpdateText("setting context") + if err := sh.Run("kubectl", "config", "use-context", constants.KindContextName); err != nil { + dspin.WarningPrinter.Printfln("default context might not be setup correct to new context: %v", err) + } + if err := sh.Run("kubectl", "config", "set-context", "--context", constants.KindContextName, "--current", "--namespace", constants.KubectlNamespace); err != nil { + dspin.WarningPrinter.Printfln("default namespace might not be setup correct to new namespace: %v", err) + } + // Create the namespace if it doesn't exist. + dspin.UpdateText("creating namespace if not exists") + if _, err := sh.Output("kubectl", "get", "namespace", constants.KubectlNamespace); err != nil { + dspin.UpdateText(fmt.Sprintf("namespace does not exist, creating namespace: %s...", constants.KubectlNamespace)) + + if err := sh.Run("kubectl", "create", "namespace", constants.KubectlNamespace); err != nil { + dspin.FailPrinter.Printfln("unable to create namespace: %v", err) + return fmt.Errorf("kubectl create namespace %s: %w", constants.KubectlNamespace, err) + } + dspin.SuccessPrinter.Printfln("namespace created: %s", constants.KubectlNamespace) + } + dspin.UpdateText("pulling docker images") + if err := sh.Run("docker", "pull", constants.DockerImageQualified); err != nil { + dspin.WarningPrinter.Printfln("docker pull: %v", err) + return fmt.Errorf("docker pull: %w", err) + } + dspin.SuccessPrinter.Println("docker image for " + constants.DockerImageQualified) + // Not working right now, can't find nodes for Kind to preload. Not critical so commenting out for now - sheldon. + // Sp.UpdateText("preloading docker image into kind cluster") + // if err := sh.Run("kind", "load", "docker-image", "quay.io/delinea/dsv-k8s:latest"); err != nil { + // return fmt.Errorf("kind load docker-image: %w", err) + // }. + dspin.SuccessPrinter.Println("(Kind) Init()") + _ = dspin.Stop() + return nil +} + +// 🗑️ Destroy tears down the Kind cluster. +func (Minikube) Destroy() error { + mtu.CheckPtermDebug() + if err := sh.Run("minikube", "delete", "--profile", constants.KindClusterName); err != nil { + pterm.Error.Printfln("minikube delete error: %v", err) + return err + } + if err := sh.Run("kubectl", "config", "unset", fmt.Sprintf("clusters.%s", constants.KindContextName)); err != nil { + pterm.Warning.Printfln("default context might not be setup correct to new context: %v", err) + } + + pterm.Success.Println("(Kind) Destroy()") + return nil +}