From 5495eb4bca472f1959a51056611355157eb0c361 Mon Sep 17 00:00:00 2001 From: Saed SayedAhmed Date: Thu, 2 Mar 2023 08:29:57 -0500 Subject: [PATCH 1/2] Add Windows Support - Adjust Go Code to Support Windows by adjusting path separator and closing the file before renaming it - Add dockerfile - Add k8s manifest --- .github/workflows/build-windows.yml | 29 ++++++++++++ .github/workflows/go.yml | 12 ++++- Dockerfile.win | 5 ++ Makefile.win | 63 ++++++++++++++++++++++++++ deployment/aws-provider-installer.yaml | 55 ++++++++++++++++++++++ provider/secret_descriptor.go | 7 +++ provider/secret_descriptor_test.go | 32 +++++++++++-- server/server.go | 2 + 8 files changed, 199 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/build-windows.yml create mode 100644 Dockerfile.win create mode 100644 Makefile.win diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 0000000..3ddf07d --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,29 @@ +name: Build Windows Image + +on: + push: + tags: + - "*" + +jobs: + build: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v3 + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: "1.20" + - name: Make build + run: make -f Makefile.win build + shell: bash + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push + run: | + docker build . -f Dockerfile.win -t ghcr.io/saedx1/secrets-store-csi-driver-provider-aws:${{ github.ref_name }} + docker push ghcr.io/saedx1/secrets-store-csi-driver-provider-aws:${{ github.ref_name }} \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 8fd78e1..1cc1d6d 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -3,9 +3,17 @@ name: Go on: [push, pull_request] jobs: - build: - runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: windows-latest + goos: windows + - os: ubuntu-latest + goos: linux + runs-on: ${{ matrix.os }} + env: + GOOS: ${{ matrix.goos }} steps: - uses: actions/checkout@v3 - name: Set up Go diff --git a/Dockerfile.win b/Dockerfile.win new file mode 100644 index 0000000..1085f0d --- /dev/null +++ b/Dockerfile.win @@ -0,0 +1,5 @@ +FROM mcr.microsoft.com/windows/nanoserver:ltsc2019 as base + +COPY ./_output/secrets-store-csi-driver-provider-aws-amd64 /secrets-store-csi-driver-provider-aws.exe + +ENTRYPOINT ["/secrets-store-csi-driver-provider-aws.exe"] diff --git a/Makefile.win b/Makefile.win new file mode 100644 index 0000000..1ab17d1 --- /dev/null +++ b/Makefile.win @@ -0,0 +1,63 @@ +$(eval AWS_REGION=$(shell echo $${REGION:-us-east-1})) +$(eval REGISTRY_NAME=$(shell echo $${PRIVREPO:-public.ecr.aws/aws-secrets-manager/secrets-store-csi-driver-provider-aws})) +$(eval REPOBASE=$(shell echo $(REGISTRY_NAME) | cut -f1 -d/)) + +ifeq ($(REPOBASE), public.ecr.aws) +ECRCMD=ecr-public +else +ECRCMD=ecr +endif + +IMAGE_NAME=secrets-store-csi-driver-provider-aws + +# Build for AMD64 and ARM64 +ARCHITECTURES=amd64 +GOOS=windows + +MAJOR_REV=1 +MINOR_REV=0 +$(eval PATCH_REV=$(shell git describe --always)) +$(eval BUILD_DATE=$(shell date -u +%Y.%m.%d.%H.%M)) +FULL_REV=$(MAJOR_REV).$(MINOR_REV).$(PATCH_REV)-$(BUILD_DATE) + +LDFLAGS?="-X github.com/aws/secrets-store-csi-driver-provider-aws/server.Version=$(FULL_REV) -extldflags "-static"" + +CHART_RELEASER_PATH ?= cr + +.PHONY: all build clean docker-login docker-buildx docker-manifest + +# Build docker image and push to AWS registry +all: build docker-login docker-buildx docker-manifest + +build: clean + $(foreach ARCH,$(ARCHITECTURES),CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(ARCH) go build -a -ldflags $(LDFLAGS) -o _output/$(IMAGE_NAME)-$(ARCH) ;) + +clean: + -rm -rf _output + -docker system prune --all --force + +docker-login: + aws --region $(AWS_REGION) $(ECRCMD) get-login-password | docker login -u AWS --password-stdin $(REPOBASE) + +# Build, tag, and push image for architecture +docker-buildx: + $(foreach ARCH,$(ARCHITECTURES),docker buildx build \ + --platform $(GOOS)/$(ARCH) \ + --no-cache \ + --push \ + -t $(REGISTRY_NAME):latest-$(ARCH) \ + -t $(REGISTRY_NAME):latest-$(GOOS)-$(ARCH) \ + -t $(REGISTRY_NAME):$(FULL_REV)-$(GOOS)-$(ARCH) \ + . ;) + +# Create and push manifest list for images +docker-manifest: + docker buildx imagetools create --tag $(REGISTRY_NAME):latest $(foreach ARCH, $(ARCHITECTURES), $(REGISTRY_NAME):latest-$(ARCH)) + docker buildx imagetools create --tag $(REGISTRY_NAME):$(FULL_REV) $(foreach ARCH, $(ARCHITECTURES), $(REGISTRY_NAME):latest-$(ARCH)) + docker buildx imagetools create --tag $(REGISTRY_NAME):$(MAJOR_REV) $(foreach ARCH, $(ARCHITECTURES), $(REGISTRY_NAME):latest-$(ARCH)) + +# Get a GitHub personal access token from the "Developer settings" section of your Github Account settings +upload-helm: + cd charts/secrets-store-csi-driver-provider-aws && ${CHART_RELEASER_PATH} package + cd charts/secrets-store-csi-driver-provider-aws && ${CHART_RELEASER_PATH} upload -o aws -r secrets-store-csi-driver-provider-aws --token $(GITHUB_TOKEN) --skip-existing + cd charts/secrets-store-csi-driver-provider-aws && ${CHART_RELEASER_PATH} index -o aws -r secrets-store-csi-driver-provider-aws --token $(GITHUB_TOKEN) --push --index-path . diff --git a/deployment/aws-provider-installer.yaml b/deployment/aws-provider-installer.yaml index 38f0a09..afeaf48 100644 --- a/deployment/aws-provider-installer.yaml +++ b/deployment/aws-provider-installer.yaml @@ -88,3 +88,58 @@ spec: type: DirectoryOrCreate nodeSelector: kubernetes.io/os: linux +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + namespace: kube-system + name: csi-secrets-store-provider-aws-windows + labels: + app: csi-secrets-store-provider-aws-windows +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: csi-secrets-store-provider-aws-windows + template: + metadata: + labels: + app: csi-secrets-store-provider-aws-windows + spec: + serviceAccountName: csi-secrets-store-provider-aws + hostNetwork: false + containers: + - name: provider-aws-installer + image: ghcr.io/saedx1/secrets-store-csi-driver-provider-aws:1.0.1 + imagePullPolicy: Always + args: + - --provider-volume=C:\k\secrets-store-csi-providers + resources: + requests: + cpu: 50m + memory: 100Mi + limits: + cpu: 50m + memory: 100Mi + securityContext: + privileged: false + allowPrivilegeEscalation: false + volumeMounts: + - mountPath: C:\k\secrets-store-csi-providers + name: providervol + - name: mountpoint-dir + mountPath: C:\var\lib\kubelet\pods + mountPropagation: HostToContainer + volumes: + - name: providervol + hostPath: + path: C:\k\secrets-store-csi-providers + - name: mountpoint-dir + hostPath: + path: C:\var\lib\kubelet\pods + type: DirectoryOrCreate + tolerations: + - operator: Exists + nodeSelector: + kubernetes.io/os: windows diff --git a/provider/secret_descriptor.go b/provider/secret_descriptor.go index f563839..da3b6f0 100644 --- a/provider/secret_descriptor.go +++ b/provider/secret_descriptor.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "regexp" + "runtime" "strings" "github.com/aws/aws-sdk-go/aws/arn" @@ -101,8 +102,14 @@ func (p *SecretDescriptor) GetFileName() (path string) { // Translate slashes to underscore if required. if len(p.translate) != 0 { fileName = strings.ReplaceAll(fileName, string(os.PathSeparator), p.translate) + if runtime.GOOS == "windows" { + fileName = strings.ReplaceAll(fileName, "/", p.translate) + } } else { fileName = strings.TrimLeft(fileName, string(os.PathSeparator)) // Strip leading slash + if runtime.GOOS == "windows" { + fileName = strings.TrimLeft(fileName, "/") // Strip leading slash + } } return fileName diff --git a/provider/secret_descriptor_test.go b/provider/secret_descriptor_test.go index d73c443..f75706b 100644 --- a/provider/secret_descriptor_test.go +++ b/provider/secret_descriptor_test.go @@ -2,6 +2,7 @@ package provider import ( "fmt" + "runtime" "strings" "testing" ) @@ -321,10 +322,19 @@ func TestGetPath(t *testing.T) { if len(descriptorList[SSMParameter]) != 1 || len(descriptorList[SecretsManager]) != 1 { t.Fatalf("Missing descriptors") } - if descriptorList[SSMParameter][0].GetMountPath() != "/mountpoint/parm1" { + + expectedParam := "/mountpoint/parm1" + expectedSecret := "/mountpoint/secret1" + + if runtime.GOOS == "windows" { + expectedParam = "\\mountpoint\\parm1" + expectedSecret = "\\mountpoint\\secret1" + } + + if descriptorList[SSMParameter][0].GetMountPath() != expectedParam { t.Errorf("Bad mount path for SSM parameter") } - if descriptorList[SecretsManager][0].GetMountPath() != "/mountpoint/secret1" { + if descriptorList[SecretsManager][0].GetMountPath() != expectedSecret { t.Errorf("Bad mount path for secret") } @@ -572,7 +582,14 @@ func TestGetPathForMultiregion(t *testing.T) { if len(descriptorList[SSMParameter]) != 1 { t.Fatalf("Missing descriptors") } - if descriptorList[SSMParameter][0].GetMountPath() != "/mountpoint/test" { + + expected := "/mountpoint/test" + + if runtime.GOOS == "windows" { + expected = "\\mountpoint\\test" + } + + if descriptorList[SSMParameter][0].GetMountPath() != expected { t.Errorf("Bad mount path for SSM parameter") } @@ -615,7 +632,14 @@ func TestVersionidsMatch(t *testing.T) { if len(descriptorList[SSMParameter]) != 1 { t.Fatalf("Missing descriptors") } - if descriptorList[SSMParameter][0].GetMountPath() != "/mountpoint/test" { + + expected := "/mountpoint/test" + + if runtime.GOOS == "windows" { + expected = "\\mountpoint\\test" + } + + if descriptorList[SSMParameter][0].GetMountPath() != expected { t.Errorf("Bad mount path for SSM parameter") } diff --git a/server/server.go b/server/server.go index 78bf8c9..dad9325 100644 --- a/server/server.go +++ b/server/server.go @@ -318,6 +318,8 @@ func (s *CSIDriverProviderServer) writeFile(secret *provider.SecretValue, mode o return nil, err } + tmpFile.Close() + // Swap out the old secret for the new err = os.Rename(tmpFile.Name(), secret.Descriptor.GetMountPath()) if err != nil { From db0b9da52c18a6d4c57fe1d8d248ea7f87c5cb79 Mon Sep 17 00:00:00 2001 From: Saed SayedAhmed Date: Mon, 6 Mar 2023 10:26:21 -0500 Subject: [PATCH 2/2] update image tag --- deployment/aws-provider-installer.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/aws-provider-installer.yaml b/deployment/aws-provider-installer.yaml index afeaf48..8ebf046 100644 --- a/deployment/aws-provider-installer.yaml +++ b/deployment/aws-provider-installer.yaml @@ -111,7 +111,7 @@ spec: hostNetwork: false containers: - name: provider-aws-installer - image: ghcr.io/saedx1/secrets-store-csi-driver-provider-aws:1.0.1 + image: ghcr.io/saedx1/secrets-store-csi-driver-provider-aws:1.0.0 imagePullPolicy: Always args: - --provider-volume=C:\k\secrets-store-csi-providers