diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..06a3493 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @rancher/observation-backup \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..56ac03c --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,25 @@ +name: CI-pullrequest + +on: [pull_request] + +env: + YQ_VERSION: v4.25.1 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name : Checkout repository + uses : actions/checkout@v4 + - name : setup go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + - name: Install mikefarah/yq + run: sudo wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq; + - name : Install helm + run : curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 |bash + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Run CI + run: make ci diff --git a/.github/workflows/e2e-ci.yaml b/.github/workflows/e2e-ci.yaml index fe3392c..139ef32 100644 --- a/.github/workflows/e2e-ci.yaml +++ b/.github/workflows/e2e-ci.yaml @@ -28,72 +28,118 @@ on: env: GOARCH: amd64 CGO_ENABLED: 0 - SETUP_GO_VERSION: '^1.18' + SETUP_GO_VERSION: '^1.22' YQ_VERSION: v4.25.1 E2E_CI: true REPO: rancher TAG: dev APISERVER_PORT: 8001 - DEFAULT_SLEEP_TIMEOUT_SECONDS: 10 + DEFAULT_SLEEP_TIMEOUT_SECONDS: 60 KUBECTL_WAIT_TIMEOUT: 120s DEBUG: ${{ github.event.inputs.debug || false }} + CLUSTER_NAME : e2e-ci-helm-project-operator permissions: contents: write jobs: + build-rancher-manager: + runs-on: ubuntu-latest + steps: + - name: Checkout rancher repository + uses: actions/checkout@v4 + with: + repository: rancher/rancher + ref: v2.8.3 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + - name: Build rancher + run: go build -o ./bin/rancher ./main.go && chmod +x ./bin/rancher + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: rancher-manager-build-artifact + path: ./bin e2e-helm-project-operator: + needs : [ + build-rancher-manager + ] runs-on: ubuntu-latest - strategy: - matrix: - k3s_version: - # k3d version list k3s | sed 's/+/-/' | sort -h - - ${{ github.event.inputs.k3s_version || 'v1.20.15-k3s1' }} + # TODO : for now hardcode k3s version + # strategy: + # matrix: + # k3s_version: + # - ${{ github.event.inputs.k3s_version || 'v1.27.7-k3s2' }} steps: - - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - - name: Install mikefarah/yq + - name : Fetch build artifacts + uses: actions/download-artifact@v4 + with: + name: rancher-manager-build-artifact + path: ./bin + - name : Debug artifacts + run : ls -l ./bin + - run : chmod +x ./bin/rancher + - name: Install mikefarah/yq run: | sudo wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq; - - - name: Perform CI - run: | - REPO=${REPO} TAG=${TAG} ./scripts/build; - REPO=${REPO} TAG=${TAG} ./scripts/package; - - - name: Provision k3d Cluster - uses: AbsaOSS/k3d-action@v2 - # k3d will automatically create a network named k3d-test-cluster-1 with the range 172.18.0.0/16 + - name: setup Go + uses: actions/setup-go@v5 with: - cluster-name: "e2e-ci-helm-project-operator" - args: >- - --agents 1 - --network "nw01" - --image docker.io/rancher/k3s:${{matrix.k3s_version}} - - - name: Import Images Into k3d + go-version: '1.22' + - name: Perform CI run: | - k3d image import ${REPO}/helm-project-operator:${TAG} -c e2e-ci-helm-project-operator; - - - name: Setup kubectl context - run: | - kubectl config use-context k3d-e2e-ci-helm-project-operator; + REPO=${REPO} TAG=${TAG} ./scripts/package; + - name : Install k3d + run : ./.github/workflows/e2e/scripts/install-k3d.sh + - name : Setup k3d cluster + run : K3S_VERSION=v1.27.7-k3s2 ./.github/workflows/e2e/scripts/setup-cluster.sh + - name : Bootstrap cluster + run : | + k3d kubeconfig get $CLUSTER_NAME > kubeconfig.yaml && export KUBECONFIG=$(pwd)/kubeconfig.yaml + CATTLE_DEV_MODE=30 CATTLE_BOOTSTRAP_PASSWORD=admin ./bin/rancher --trace=false --add-local=true --no-cacerts & + # name: Provision k3d Cluster + # uses: AbsaOSS/k3d-action@v2 + # # k3d will automatically create a network named k3d-test-cluster-1 with the range 172.18.0.0/16 + # with: + # cluster-name: "e2e-ci-helm-project-operator" + # args: >- + # --agents 1 + # --network "nw01" + # --image docker.io/rancher/k3s:${{matrix.k3s_version}} + # - + # name: Import Images Into k3d + # run: | + # k3d image import ${REPO}/helm-project-operator:${TAG} -c e2e-ci-helm-project-operator; + # - + # name: Setup kubectl context + # run: | + # kubectl config use-context k3d-e2e-ci-helm-project-operator; - name: Set Up Tmate Debug Session if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.enable_tmate == 'true' }} uses: mxschmitt/action-tmate@v3 timeout-minutes: 15 with: - limit-access-to-actor: true + limit-access-to-actor: true + + # - + # name: Install rancher manager + # run: ./.github/workflows/e2e/scripts/install-rancher.sh; + # - + # name: Validate rancher manager + # run: ./.github/workflows/e2e/scripts/validate-rancher.sh; - name: Install Helm Project Operator run: ./.github/workflows/e2e/scripts/install-helm-project-operator.sh; - name: Check if Helm Project Operator is up run: ./.github/workflows/e2e/scripts/validate-helm-project-operator.sh; + - name: Check if Project Registration Namespace is auto-created on namespace detection run: ./.github/workflows/e2e/scripts/create-project-namespace.sh; diff --git a/.github/workflows/e2e/scripts/create-project-namespace.sh b/.github/workflows/e2e/scripts/create-project-namespace.sh index 480afcc..92a8014 100755 --- a/.github/workflows/e2e/scripts/create-project-namespace.sh +++ b/.github/workflows/e2e/scripts/create-project-namespace.sh @@ -6,9 +6,11 @@ source $(dirname $0)/entry cd $(dirname $0)/../../../.. kubectl create namespace e2e-hpo || true -kubectl label namespace e2e-hpo field.cattle.io/projectId=p-example --overwrite +kubectl annotate namespace e2e-hpo field.cattle.io/projectId=local:p-example --overwrite sleep "${DEFAULT_SLEEP_TIMEOUT_SECONDS}" if ! kubectl get namespace cattle-project-p-example; then + echo "DEBUG" + kubectl get ns echo "ERROR: Expected cattle-project-p-example namespace to exist after ${DEFAULT_SLEEP_TIMEOUT_SECONDS} seconds, not found" exit 1 fi diff --git a/.github/workflows/e2e/scripts/create-projecthelmchart.sh b/.github/workflows/e2e/scripts/create-projecthelmchart.sh index 00a20ca..7beccd5 100755 --- a/.github/workflows/e2e/scripts/create-projecthelmchart.sh +++ b/.github/workflows/e2e/scripts/create-projecthelmchart.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e +set -x source $(dirname $0)/entry diff --git a/.github/workflows/e2e/scripts/install-helm-project-operator.sh b/.github/workflows/e2e/scripts/install-helm-project-operator.sh index 40a4268..bb4771a 100755 --- a/.github/workflows/e2e/scripts/install-helm-project-operator.sh +++ b/.github/workflows/e2e/scripts/install-helm-project-operator.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e +set -x source $(dirname $0)/entry diff --git a/.github/workflows/e2e/scripts/install-k3d.sh b/.github/workflows/e2e/scripts/install-k3d.sh new file mode 100755 index 0000000..51ed39f --- /dev/null +++ b/.github/workflows/e2e/scripts/install-k3d.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e +set -x + +K3D_URL=https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh +DEFAULT_K3D_VERSION=v5.4.6 + +install_k3d(){ + local k3dVersion=${K3D_VERSION:-${DEFAULT_K3D_VERSION}} + echo -e "Downloading k3d@${k3dVersion} see: ${K3D_URL}" + curl --silent --fail ${K3D_URL} | TAG=${k3dVersion} bash +} + +install_k3d + +k3d version \ No newline at end of file diff --git a/.github/workflows/e2e/scripts/install-rancher.sh b/.github/workflows/e2e/scripts/install-rancher.sh new file mode 100755 index 0000000..77f510b --- /dev/null +++ b/.github/workflows/e2e/scripts/install-rancher.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +helm repo add rancher-stable https://releases.rancher.com/server-charts/stable + +helm repo update + +kubectl create namespace cattle-system + +helm install -n cattle-system rancher rancher-stable/rancher \ No newline at end of file diff --git a/.github/workflows/e2e/scripts/setup-cluster.sh b/.github/workflows/e2e/scripts/setup-cluster.sh new file mode 100755 index 0000000..4a92163 --- /dev/null +++ b/.github/workflows/e2e/scripts/setup-cluster.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +source ./scripts/version + +if [ -z "$CLUSTER_NAME" ]; then + echo "CLUSTER_NAME must be specified when setting up a cluster" + exit 1 +fi + +if [ -z "$K3S_VERSION" ]; then + echo "K3S_VERSION must be specified when setting up a cluster, use $(k3d version list k3s) to find valid versions" + exit 1 +fi + +# waits until all nodes are ready +wait_for_nodes(){ + timeout=120 + start_time=$(date +%s) + echo "wait until all agents are ready" + while : + do + current_time=$(date +%s) + elapsed_time=$((current_time - start_time)) + if [ $elapsed_time -ge $timeout ]; then + echo "Timeout reached, exiting..." + exit 1 + fi + + readyNodes=1 + statusList=$(kubectl get nodes --no-headers | awk '{ print $2}') + # shellcheck disable=SC2162 + while read status + do + current_time=$(date +%s) + elapsed_time=$((current_time - start_time)) + if [ $elapsed_time -ge $timeout ]; then + echo "Timeout reached, exiting..." + exit 1 + fi + if [ "$status" == "NotReady" ] || [ "$status" == "" ] + then + readyNodes=0 + break + fi + done <<< "$(echo -e "$statusList")" + # all nodes are ready; exit + if [[ $readyNodes == 1 ]] + then + break + fi + sleep 1 + done +} + +k3d cluster delete $CLUSTER_NAME || true +k3d cluster create $CLUSTER_NAME --image "docker.io/rancher/k3s:${K3S_VERSION}" + +wait_for_nodes + +echo "$CLUSTER_NAME ready" + +kubectl cluster-info --context k3d-${CLUSTER_NAME} +kubectl config use-context k3d-${CLUSTER_NAME} +kubectl get nodes -o wide + +echo "Importing image ${IMAGE}" +k3d image import ${IMAGE} -c $CLUSTER_NAME \ No newline at end of file diff --git a/.github/workflows/e2e/scripts/validate-rancher.sh b/.github/workflows/e2e/scripts/validate-rancher.sh new file mode 100755 index 0000000..eb7af96 --- /dev/null +++ b/.github/workflows/e2e/scripts/validate-rancher.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +sleep "${DEFAULT_SLEEP_TIMEOUT_SECONDS}" +# Check deployment status +kubectl -n cattle-system rollout status deploy/rancher + +# Capture the exit status of the previous command +exit_status=$? + +if [ $exit_status -eq 0 ]; then + echo "rancher deployment is healthy." +else + echo "rancher deployment is not healthy." +fi + +exit $exit_status diff --git a/.github/workflows/label-all-new-issues.yaml b/.github/workflows/label-all-new-issues.yaml index 3028a1a..457043e 100644 --- a/.github/workflows/label-all-new-issues.yaml +++ b/.github/workflows/label-all-new-issues.yaml @@ -18,5 +18,5 @@ jobs: - name: Label issues uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 with: - add-labels: "team/area3" + add-labels: "team/observability&backup" repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..4699dde --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,36 @@ +name: golangci-lint +on: + pull_request: + paths-ignore: + - 'docs/**' + - '*.md' + - '.gitignore' + - 'CODEOWNERS' + - 'LICENSE' + - 'scripts/' + - 'Makefile' + +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + # hack we require embedding an example chart in the dummy HPO + - name: Place empty chart + run: mkdir -p ./bin/example-chart && touch ./bin/example-chart/example-chart.tgz.base64 + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + # Require: The version of golangci-lint to use. + # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. + # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. + version: v1.56 \ No newline at end of file diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml deleted file mode 100644 index a9a07c8..0000000 --- a/.github/workflows/pull-request.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: CI-pullrequest - -on: [pull_request] - -jobs: - build: - runs-on: ubuntu-latest - container: - image: rancher/dapper:v0.5.4 - steps: - - uses: actions/checkout@v1 - - name: Run CI - run: dapper ci diff --git a/.golangci.json b/.golangci.json index 26c5edc..a3db992 100644 --- a/.golangci.json +++ b/.golangci.json @@ -12,17 +12,19 @@ ] }, "run": { - "skip-files": [ - "/zz_generated_" - ], + "issues": { + "exclude-files": [ + "/zz_generated_" + ] + }, "deadline": "5m" }, - "issues": { - "exclude-rules": [ - { - "linters": "revive", - "text": "should have comment or be unexported" - } - ] - } -} + "issues": { + "exclude-rules": [ + { + "linters": "revive", + "text": "should have comment or be unexported" + } + ] + } +} \ No newline at end of file diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..a3c4451 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,37 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy +builds: + - id: helm-project-operator + main: . + goos: + - linux + goarch: + - amd64 + - arm64 + binary: helm-project-operator + ldflags: + - -s + - -w + flags: + - -trimpath + env: + - CGO_ENABLED=0 +archives: + - id: helm-project-operator + builds: + - helm-project-operator + name_template: '{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index d01b8a5..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @rancher/observation-backup diff --git a/MAINTAINERS.md b/MAINTAINERS.md deleted file mode 100644 index 79f91eb..0000000 --- a/MAINTAINERS.md +++ /dev/null @@ -1 +0,0 @@ -Arvind Iyengar (arvindiyengar@suse.com / @aiyengar2) \ No newline at end of file diff --git a/Makefile b/Makefile index 5d7b47e..348fabd 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,8 @@ TARGETS := $(shell ls scripts) -.dapper: - @echo Downloading dapper - @curl -sL https://releases.rancher.com/dapper/latest/dapper-$$(uname -s)-$$(uname -m) > .dapper.tmp - @@chmod +x .dapper.tmp - @./.dapper.tmp -v - @mv .dapper.tmp .dapper - -$(TARGETS): .dapper - ./.dapper $@ +$(TARGETS): + ./scripts/$@ .DEFAULT_GOAL := default -.PHONY: $(TARGETS) +.PHONY: $(TARGETS) \ No newline at end of file diff --git a/dummy.go b/dummy.go index 1eaf01e..7354295 100644 --- a/dummy.go +++ b/dummy.go @@ -13,6 +13,7 @@ import ( _ "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io" _ "github.com/rancher/wrangler/pkg/generated/controllers/networking.k8s.io" "github.com/rancher/wrangler/pkg/kubeconfig" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -41,10 +42,11 @@ type DummyOperator struct { Kubeconfig string `usage:"Kubeconfig file"` } -func (o *DummyOperator) Run(cmd *cobra.Command, args []string) error { +func (o *DummyOperator) Run(cmd *cobra.Command, _ []string) error { go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() + logrus.SetReportCaller(true) debugConfig.MustSetupDebug() cfg := kubeconfig.GetNonInteractiveClientConfig(o.Kubeconfig) diff --git a/go.mod b/go.mod index d691231..523dae8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/rancher/helm-project-operator -go 1.19 +go 1.22 replace ( k8s.io/api => k8s.io/api v0.22.3 diff --git a/go.sum b/go.sum index 6f37ac9..952eaec 100644 --- a/go.sum +++ b/go.sum @@ -836,6 +836,7 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -847,6 +848,7 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= diff --git a/package/Dockerfile b/package/Dockerfile index 4d9379c..c7ea8ed 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -1,8 +1,29 @@ -FROM registry.suse.com/bci/bci-micro:15.4 +FROM registry.suse.com/bci/golang:1.22 as builder +ARG helm-version=3.14.3 +RUN zypper refresh +RUN zypper install -y gawk wget +# RUN wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq && \ +# chmod +x /usr/local/bin/yq +# RUN which yq +# RUN curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" +# RUN mv kubectl /usr/local/bin && chmod +x /usr/local/bin/kubectl +# # TODO : debug +# RUN which kubectl +RUN curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 |bash +# TODO : debug +RUN which helm +# RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.2 +WORKDIR /usr/src/app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN make build + +FROM registry.suse.com/bci/bci-micro:latest RUN echo 'helmprojectoperator:x:1000:1000::/home/helmprojectoperator:/bin/bash' >> /etc/passwd && \ echo 'helmprojectoperator:x:1000:' >> /etc/group && \ mkdir /home/helmprojectoperator && \ chown -R helmprojectoperator:helmprojectoperator /home/helmprojectoperator -COPY bin/helm-project-operator /usr/bin/ +COPY --from=builder /usr/src/app/bin/helm-project-operator /usr/bin/ USER helmprojectoperator CMD ["helm-project-operator"] diff --git a/pkg/apis/helm.cattle.io/v1alpha1/doc.go b/pkg/apis/helm.cattle.io/v1alpha1/doc.go index 31a7ddd..20da9d2 100644 --- a/pkg/apis/helm.cattle.io/v1alpha1/doc.go +++ b/pkg/apis/helm.cattle.io/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_deepcopy.go b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_deepcopy.go index 3c249e3..24b0d00 100644 --- a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_deepcopy.go +++ b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_list_types.go b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_list_types.go index 39c88b5..1dcc3ad 100644 --- a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_list_types.go +++ b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_list_types.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_register.go b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_register.go index 7d5f1af..3591dfa 100644 --- a/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_register.go +++ b/pkg/apis/helm.cattle.io/v1alpha1/zz_generated_register.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/apis/helm.cattle.io/zz_generated_register.go b/pkg/apis/helm.cattle.io/zz_generated_register.go index 89a2a02..11c331c 100644 --- a/pkg/apis/helm.cattle.io/zz_generated_register.go +++ b/pkg/apis/helm.cattle.io/zz_generated_register.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/controllers/common/operatorlabels.go b/pkg/controllers/common/operatorlabels.go index 38a0d66..235dbd3 100644 --- a/pkg/controllers/common/operatorlabels.go +++ b/pkg/controllers/common/operatorlabels.go @@ -36,9 +36,10 @@ func GetCommonLabels(projectID string) map[string]string { labels := map[string]string{ HelmProjectOperatedLabel: "true", } - if len(projectID) != 0 { - labels[HelmProjectOperatorProjectLabel] = projectID - } + // FIXME: this causes webhook to reject it + // if len(projectID) != 0 { + // labels[HelmProjectOperatorProjectLabel] = projectID + // } return labels } @@ -56,7 +57,8 @@ func GetProjectNamespaceLabels(projectID, projectLabel, projectLabelValue string if isOrphaned { labels[HelmProjectOperatedNamespaceOrphanedLabel] = "true" } - labels[projectLabel] = projectLabelValue + // FIXME: this is not allowed by webhook + // labels[projectLabel] = projectLabelValue return labels } diff --git a/pkg/controllers/hardened/controller.go b/pkg/controllers/hardened/controller.go index 8a8f7ac..b9c898c 100644 --- a/pkg/controllers/hardened/controller.go +++ b/pkg/controllers/hardened/controller.go @@ -41,6 +41,7 @@ func Register( namespaceCache: namespaceCache, serviceaccounts: serviceaccounts, networkpolicies: networkpolicies, + opts: opts, } h.initResolvers(ctx) @@ -48,7 +49,7 @@ func Register( namespaces.OnChange(ctx, "harden-hpo-operated-namespace", h.OnChange) } -func (h *handler) OnChange(name string, namespace *corev1.Namespace) (*corev1.Namespace, error) { +func (h *handler) OnChange(_ /*name*/ string, namespace *corev1.Namespace) (*corev1.Namespace, error) { if namespace == nil { return namespace, nil } diff --git a/pkg/controllers/hardened/resolvers.go b/pkg/controllers/hardened/resolvers.go index 2daa98a..8a960ec 100644 --- a/pkg/controllers/hardened/resolvers.go +++ b/pkg/controllers/hardened/resolvers.go @@ -46,7 +46,7 @@ func (h *handler) resolveHardenedProjectRegistrationNamespaceData(namespace, nam return nil, nil } -func (h *handler) resolveServiceAccount(namespace, name string, serviceAccount *corev1.ServiceAccount) ([]relatedresource.Key, error) { +func (h *handler) resolveServiceAccount(namespace, name string, _ *corev1.ServiceAccount) ([]relatedresource.Key, error) { // check if name matches if name == defaultServiceAccountName { return []relatedresource.Key{{ @@ -56,7 +56,7 @@ func (h *handler) resolveServiceAccount(namespace, name string, serviceAccount * return nil, nil } -func (h *handler) resolveNetworkPolicy(namespace, name string, networkPolicy *networkingv1.NetworkPolicy) ([]relatedresource.Key, error) { +func (h *handler) resolveNetworkPolicy(namespace, name string, _ *networkingv1.NetworkPolicy) ([]relatedresource.Key, error) { // check if name matches if name == defaultNetworkPolicyName { return []relatedresource.Key{{ diff --git a/pkg/controllers/namespace/controller.go b/pkg/controllers/namespace/controller.go index 6e18003..1f830ac 100644 --- a/pkg/controllers/namespace/controller.go +++ b/pkg/controllers/namespace/controller.go @@ -106,7 +106,12 @@ func Register( // Single Namespace Handler -func (h *handler) OnSingleNamespaceChange(name string, namespace *corev1.Namespace) (*corev1.Namespace, error) { +func (h *handler) OnSingleNamespaceChange(_ /*name*/ string, namespace *corev1.Namespace) (*corev1.Namespace, error) { + // TODO : figure out how to handle this edgecase + if namespace == nil { + // namespace has been deleted + return namespace, nil + } if namespace.Name != h.systemNamespace { // enqueue system namespace to ensure that rolebindings are updated @@ -129,7 +134,7 @@ func (h *handler) OnSingleNamespaceChange(name string, namespace *corev1.Namespa // Multiple Namespaces Handler -func (h *handler) OnMultiNamespaceChange(name string, namespace *corev1.Namespace) (*corev1.Namespace, error) { +func (h *handler) OnMultiNamespaceChange(_ /*name*/ string, namespace *corev1.Namespace) (*corev1.Namespace, error) { if namespace == nil { logrus.Debugf("OnMultiNamespaceChange() called with no namespace.") return namespace, nil diff --git a/pkg/controllers/namespace/reconcilers.go b/pkg/controllers/namespace/reconcilers.go index 8d12406..e52fb3b 100644 --- a/pkg/controllers/namespace/reconcilers.go +++ b/pkg/controllers/namespace/reconcilers.go @@ -23,8 +23,7 @@ func (h *handler) addReconcilers(apply apply.Apply, dynamic dynamic.Interface) a NamespaceableResourceInterface: dynamic.Resource(corev1.SchemeGroupVersion.WithResource("configmaps")), } apply = apply.WithReconciler(corev1.SchemeGroupVersion.WithKind("ConfigMap"), r.deleteAndReplace) - - logrus.Infof("Adding reconcilers on the apply object %s", apply) + logrus.Debugf("Adding reconcilers on the apply object %s", apply) return apply } diff --git a/pkg/controllers/namespace/resolvers.go b/pkg/controllers/namespace/resolvers.go index 7b09e9b..9ab2e9f 100644 --- a/pkg/controllers/namespace/resolvers.go +++ b/pkg/controllers/namespace/resolvers.go @@ -34,7 +34,7 @@ func (h *handler) resolveProjectRegistrationNamespaceData(namespace, name string return nil, nil } -func (h *handler) resolveConfigMap(namespace, name string, configmap *corev1.ConfigMap) ([]relatedresource.Key, error) { +func (h *handler) resolveConfigMap(namespace, name string, _ *corev1.ConfigMap) ([]relatedresource.Key, error) { // check if name matches if name == h.getConfigMapName() { return []relatedresource.Key{{ diff --git a/pkg/controllers/project/controller.go b/pkg/controllers/project/controller.go index a14b39f..40e119a 100644 --- a/pkg/controllers/project/controller.go +++ b/pkg/controllers/project/controller.go @@ -128,7 +128,7 @@ func Register( }) remove.RegisterScopedOnRemoveHandler(ctx, projectHelmCharts, "on-project-helm-chart-remove", - func(key string, obj runtime.Object) (bool, error) { + func(_ /*key*/ string, obj runtime.Object) (bool, error) { if obj == nil { return false, nil } @@ -315,7 +315,7 @@ func (h *handler) OnChange(projectHelmChart *v1alpha1.ProjectHelmChart, projectH return objs, projectHelmChartStatus, nil } -func (h *handler) OnRemove(key string, projectHelmChart *v1alpha1.ProjectHelmChart) (*v1alpha1.ProjectHelmChart, error) { +func (h *handler) OnRemove(_ /*key*/ string, projectHelmChart *v1alpha1.ProjectHelmChart) (*v1alpha1.ProjectHelmChart, error) { if projectHelmChart == nil { return nil, nil } diff --git a/pkg/controllers/project/resolvers.go b/pkg/controllers/project/resolvers.go index 0a03da8..de60154 100644 --- a/pkg/controllers/project/resolvers.go +++ b/pkg/controllers/project/resolvers.go @@ -46,7 +46,7 @@ func (h *handler) initResolvers(ctx context.Context) { // Project Release Namespace -func (h *handler) resolveProjectReleaseNamespace(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { +func (h *handler) resolveProjectReleaseNamespace(_ /*namespace*/, _ /*name*/ string, obj runtime.Object) ([]relatedresource.Key, error) { if obj == nil { return nil, nil } @@ -62,7 +62,7 @@ func (h *handler) resolveProjectReleaseNamespace(namespace, name string, obj run // System Namespace Data -func (h *handler) resolveSystemNamespaceData(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { +func (h *handler) resolveSystemNamespaceData(namespace, _ /*name*/ string, obj runtime.Object) ([]relatedresource.Key, error) { if namespace != h.systemNamespace { return nil, nil } @@ -98,7 +98,7 @@ func (h *handler) resolveProjectRegistrationNamespaceData(namespace, name string return nil, nil } -func (h *handler) resolveProjectRegistrationNamespaceRoleBinding(namespace, name string, rb *rbacv1.RoleBinding) ([]relatedresource.Key, error) { +func (h *handler) resolveProjectRegistrationNamespaceRoleBinding(namespace, _ /*name*/ string, rb *rbacv1.RoleBinding) ([]relatedresource.Key, error) { namespaceObj, err := h.namespaceCache.Get(namespace) if err != nil { logrus.Debugf("Namespace not found %s: ", namespace) @@ -134,7 +134,7 @@ func (h *handler) resolveProjectRegistrationNamespaceRoleBinding(namespace, name return keys, nil } -func (h *handler) resolveClusterRoleBinding(namespace, name string, crb *rbacv1.ClusterRoleBinding) ([]relatedresource.Key, error) { +func (h *handler) resolveClusterRoleBinding(_ /*namespace*/, _ /*name*/ string, crb *rbacv1.ClusterRoleBinding) ([]relatedresource.Key, error) { // we want to re-enqueue the ProjectHelmChart if the rolebinding's ref points to one of the operator default roles _, isDefaultRoleRef := common.IsDefaultClusterRoleRef(h.opts, crb.RoleRef.Name) if !isDefaultRoleRef { @@ -174,7 +174,7 @@ func (h *handler) resolveClusterRoleBinding(namespace, name string, crb *rbacv1. // Project Release Namespace Data -func (h *handler) resolveProjectReleaseNamespaceData(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { +func (h *handler) resolveProjectReleaseNamespaceData(_ /*namespace*/, _ /*name*/ string, obj runtime.Object) ([]relatedresource.Key, error) { if obj == nil { return nil, nil } diff --git a/pkg/controllers/project/status.go b/pkg/controllers/project/status.go index 40f50a6..afe5fa1 100644 --- a/pkg/controllers/project/status.go +++ b/pkg/controllers/project/status.go @@ -8,7 +8,7 @@ import ( ) // getCleanupStatus returns the status on seeing the cleanup label on a ProjectHelmChart -func (h *handler) getCleanupStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getCleanupStatus(projectHelmChart *v1alpha1.ProjectHelmChart, _ v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { return v1alpha1.ProjectHelmChartStatus{ Status: "AwaitingOperatorRedeployment", StatusMessage: fmt.Sprintf( @@ -21,7 +21,7 @@ func (h *handler) getCleanupStatus(projectHelmChart *v1alpha1.ProjectHelmChart, } // getUnableToCreateHelmReleaseStatus returns the status on seeing a conflicting ProjectHelmChart already tracking the desired Helm release -func (h *handler) getUnableToCreateHelmReleaseStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus, err error) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getUnableToCreateHelmReleaseStatus(projectHelmChart *v1alpha1.ProjectHelmChart, _ v1alpha1.ProjectHelmChartStatus, err error) v1alpha1.ProjectHelmChartStatus { releaseNamespace, releaseName := h.getReleaseNamespaceAndName(projectHelmChart) return v1alpha1.ProjectHelmChartStatus{ Status: "UnableToCreateHelmRelease", @@ -34,7 +34,7 @@ func (h *handler) getUnableToCreateHelmReleaseStatus(projectHelmChart *v1alpha1. // getNoTargetNamespacesStatus returns the status on seeing that a ProjectHelmChart's projectNamespaceSelector (or // the Project Registration Namespace's namespaceSelector) targets no namespaces -func (h *handler) getNoTargetNamespacesStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getNoTargetNamespacesStatus(_ *v1alpha1.ProjectHelmChart, _ v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { return v1alpha1.ProjectHelmChartStatus{ Status: "NoTargetProjectNamespaces", StatusMessage: "There are no project namespaces to deploy a ProjectHelmChart.", @@ -42,7 +42,7 @@ func (h *handler) getNoTargetNamespacesStatus(projectHelmChart *v1alpha1.Project } // getValuesParseErrorStatus returns the status on encountering an error with parsing the provided contents of spec.values on the ProjectHelmChart -func (h *handler) getValuesParseErrorStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus, err error) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getValuesParseErrorStatus(_ *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus, err error) v1alpha1.ProjectHelmChartStatus { // retain existing status if possible projectHelmChartStatus.Status = "UnableToParseValues" projectHelmChartStatus.StatusMessage = fmt.Sprintf("Unable to convert provided spec.values into valid configuration of ProjectHelmChart: %s", err) @@ -52,7 +52,7 @@ func (h *handler) getValuesParseErrorStatus(projectHelmChart *v1alpha1.ProjectHe // getWaitingForDashboardValuesStatus returns the transitionary status that occurs after deploying a Helm chart but before a dashboard configmap is created // If a ProjectHelmChart is stuck in this status, it is likely either an error on the Operator for not creating this ConfigMap or there might be an issue // with the underlying Job ran by the child HelmChart resource created on this ProjectHelmChart's behalf -func (h *handler) getWaitingForDashboardValuesStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getWaitingForDashboardValuesStatus(_ *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { // retain existing status projectHelmChartStatus.Status = "WaitingForDashboardValues" projectHelmChartStatus.StatusMessage = "Waiting for status.dashboardValues content to be provided by the deployed Helm release, but HelmChart and HelmRelease should be deployed." @@ -61,7 +61,7 @@ func (h *handler) getWaitingForDashboardValuesStatus(projectHelmChart *v1alpha1. } // getDeployedStatus returns the status that indicates the ProjectHelmChart is successfully deployed -func (h *handler) getDeployedStatus(projectHelmChart *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { +func (h *handler) getDeployedStatus(_ *v1alpha1.ProjectHelmChart, projectHelmChartStatus v1alpha1.ProjectHelmChartStatus) v1alpha1.ProjectHelmChartStatus { // retain existing status projectHelmChartStatus.Status = "Deployed" projectHelmChartStatus.StatusMessage = "ProjectHelmChart has been successfully deployed!" diff --git a/pkg/crd/crds.go b/pkg/crd/crds.go index ea54e7f..ac042e8 100644 --- a/pkg/crd/crds.go +++ b/pkg/crd/crds.go @@ -87,15 +87,15 @@ func Print(out io.Writer, depOut io.Writer) { if err != nil { logrus.Fatalf("%s", err) } - if err := print(out, objs); err != nil { + if err := printObjs(out, objs); err != nil { logrus.Fatalf("%s", err) } - if err := print(depOut, depObjs); err != nil { + if err := printObjs(depOut, depObjs); err != nil { logrus.Fatalf("%s", err) } } -func print(out io.Writer, objs []runtime.Object) error { +func printObjs(out io.Writer, objs []runtime.Object) error { data, err := yaml.Export(objs...) if err != nil { return err diff --git a/pkg/generated/controllers/helm.cattle.io/factory.go b/pkg/generated/controllers/helm.cattle.io/factory.go index 062d020..38c58cd 100644 --- a/pkg/generated/controllers/helm.cattle.io/factory.go +++ b/pkg/generated/controllers/helm.cattle.io/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/generated/controllers/helm.cattle.io/interface.go b/pkg/generated/controllers/helm.cattle.io/interface.go index bc93dd0..aaee3d7 100644 --- a/pkg/generated/controllers/helm.cattle.io/interface.go +++ b/pkg/generated/controllers/helm.cattle.io/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/generated/controllers/helm.cattle.io/v1alpha1/interface.go b/pkg/generated/controllers/helm.cattle.io/v1alpha1/interface.go index e723976..a353080 100644 --- a/pkg/generated/controllers/helm.cattle.io/v1alpha1/interface.go +++ b/pkg/generated/controllers/helm.cattle.io/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/generated/controllers/helm.cattle.io/v1alpha1/projecthelmchart.go b/pkg/generated/controllers/helm.cattle.io/v1alpha1/projecthelmchart.go index e46168a..a9c3d03 100644 --- a/pkg/generated/controllers/helm.cattle.io/v1alpha1/projecthelmchart.go +++ b/pkg/generated/controllers/helm.cattle.io/v1alpha1/projecthelmchart.go @@ -1,5 +1,5 @@ /* -Copyright 2023 Rancher Labs, Inc. +Copyright 2024 Rancher Labs, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/scripts/build b/scripts/build index 271d51c..c2c9eb2 100755 --- a/scripts/build +++ b/scripts/build @@ -8,12 +8,13 @@ cd $(dirname $0)/.. ./scripts/build-chart mkdir -p bin +GO_BUILD_FLAGS="-gcflags=all=-trimpath=${GOPATH} -asmflags all=-trimpath=${GOPATH}" if [ "$(uname)" = "Linux" ]; then - OTHER_LINKFLAGS="-extldflags -static -s" + OTHER_LINKFLAGS="-extldflags -static -s -w" fi LINKFLAGS="-X github.com/rancher/helm-project-operator/pkg/version.Version=$VERSION" LINKFLAGS="-X github.com/rancher/helm-project-operator/pkg/version.GitCommit=$COMMIT $LINKFLAGS" -CGO_ENABLED=0 go build -ldflags "$LINKFLAGS $OTHER_LINKFLAGS" -o bin/helm-project-operator +CGO_ENABLED=0 go build $GO_BUILD_FLAGS -ldflags "$LINKFLAGS $OTHER_LINKFLAGS" -o bin/helm-project-operator if [ "$CROSS" = "true" ] && [ "$ARCH" = "amd64" ]; then GOOS=darwin go build -ldflags "$LINKFLAGS" -o bin/helm-project-operator-darwin GOOS=windows go build -ldflags "$LINKFLAGS" -o bin/helm-project-operator-windows diff --git a/scripts/package b/scripts/package index 0df435b..9d924dd 100755 --- a/scripts/package +++ b/scripts/package @@ -6,7 +6,6 @@ source $(dirname $0)/version cd $(dirname $0)/.. mkdir -p dist/artifacts -cp bin/helm-project-operator dist/artifacts/helm-project-operator${SUFFIX} IMAGE=${REPO}/helm-project-operator:${TAG} DOCKERFILE=package/Dockerfile diff --git a/scripts/validate b/scripts/validate index 7f98128..b95a81c 100755 --- a/scripts/validate +++ b/scripts/validate @@ -7,15 +7,7 @@ echo Running validation PACKAGES="$(go list ./...)" -if ! command -v golangci-lint; then - echo Skipping validation: no golangci-lint available - exit -fi - echo Running validation -echo Running: golangci-lint -golangci-lint run - echo Running: go fmt test -z "$(go fmt ${PACKAGES} | tee /dev/stderr)" diff --git a/scripts/version b/scripts/version index 1646092..b5d2047 100755 --- a/scripts/version +++ b/scripts/version @@ -25,3 +25,4 @@ REPO=${REPO:-rancher} if echo $TAG | grep -q dirty; then TAG=dev fi +IMAGE=${REPO}/helm-project-operator:${TAG} \ No newline at end of file