diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5714ade0..9b38024b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,14 +8,12 @@ jobs: name: Build shell-operator binary runs-on: ubuntu-latest steps: - - name: Set up Go 1.23 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.23" - + go-version: "1.25.5" - name: Check out shell-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4.2.3 @@ -23,19 +21,21 @@ jobs: path: | ~/go/pkg/mod key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} + - name: Check generated code is up to date + run: | + make generate + git diff --exit-code || (echo 'Regenerated code does not match source, please run "make generate"' && exit 1) - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Build binary run: | export GOOS=linux go build ./cmd/shell-operator - # MacOS build works fine because jq package already has static libraries. # Windows build requires jq compilation, this should be done in libjq-go. # TODO Does cross-compile can help here? diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index 2ee4d10a..cea78502 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -1,14 +1,11 @@ name: PR Checks - on: pull_request: types: [opened, labeled, unlabeled, synchronize] - jobs: release-label: name: Release note label runs-on: ubuntu-latest - steps: - name: Check minimum labels uses: mheap/github-action-required-labels@v5 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 2f7afa90..8213054d 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,11 +1,9 @@ name: Docs - on: push: branches: - main pull_request: - jobs: deploy: runs-on: ubuntu-24.04 @@ -13,14 +11,11 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }} steps: - uses: actions/checkout@v4 - - name: Setup mdBook uses: peaceiris/actions-mdbook@v2 with: mdbook-version: '0.4.10' - - run: mdbook build docs - - name: Deploy uses: peaceiris/actions-gh-pages@v4 if: ${{ github.ref == 'refs/heads/main' }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 60302deb..25a854e1 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -4,20 +4,17 @@ name: Lint on: pull_request: types: [opened, synchronize] - jobs: run_linter: name: Run linter runs-on: ubuntu-latest steps: - - name: Set up Go 1.23 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.23" - + go-version: "1.25.5" - name: Check out shell-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4.2.3 @@ -27,19 +24,15 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Run golangci-lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b . v2.1.6 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b . v2.8.0 ./golangci-lint run --build-tags integration,test - - codespell: name: Run codespell runs-on: ubuntu-latest @@ -47,10 +40,8 @@ jobs: - uses: actions/setup-python@v5 with: python-version: 3.8 - - name: Check out addon-operator code uses: actions/checkout@v4 - - name: Run codespell run: | pip install codespell==v1.17.1 diff --git a/.github/workflows/publish-dev.yaml b/.github/workflows/publish-dev.yaml index 022a83e5..cb2a79c6 100644 --- a/.github/workflows/publish-dev.yaml +++ b/.github/workflows/publish-dev.yaml @@ -11,7 +11,6 @@ env: BUILDX_PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7" BUILDX_PLATFORMS_AMD64: "linux/amd64" GHCR_IO_REPO: ghcr.io/flant/shell-operator-dev - jobs: check: name: Check and remove label @@ -60,7 +59,6 @@ jobs: } catch (e) { console.log(`Error occurred while remove label. Possibly label is already removed. Ignore '${typeof e}' error.`); } - publish_dev_image: name: Build and publish runs-on: ubuntu-latest @@ -69,7 +67,6 @@ jobs: if: needs.check.outputs.run_publish == 'true' steps: - uses: actions/checkout@v4 - - name: Prepare environment env: BUILD_MULTI_ARCH: ${{ needs.check.outputs.build_multi_arch }} @@ -93,26 +90,22 @@ jobs: echo "BUILD_MULTI_ARCH = ${BUILD_MULTI_ARCH}" echo "BUILDX_PLATFORMS = ${BUILDX_PLATFORMS}" echo "=========================================" - - name: Set up QEMU if: needs.check.outputs.build_multi_arch == 'true' uses: docker/setup-qemu-action@v3.6.0 with: platforms: "${{ env.QEMU_PLATFORMS }}" - - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 with: version: latest - - name: Login to Github Container Registry uses: docker/login-action@v3.4.0 with: registry: ghcr.io username: ${{ secrets.GHCR_IO_USER }} password: ${{ secrets.GHCR_IO_PASS }} - - name: Build and push using buildx run: | echo "Build ${GHCR_IO_IMAGE_NAME} with version '${APP_VERSION}'" @@ -121,32 +114,6 @@ jobs: --build-arg appVersion=$APP_VERSION \ --tag $GHCR_IO_IMAGE_NAME \ --push . - - name: Inspect binaries if: needs.check.outputs.build_multi_arch == 'true' - run: | - # Image for one arhitecture has digest in config field. - # Image with multiple manifests has digest in each manifest. - manifests=$(docker buildx imagetools inspect "${GHCR_IO_IMAGE_NAME}" --raw) - if grep manifests <<<"${manifests}" 2>&1 >/dev/null ; then - jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" \ - | while read digest platform ; do - image=${GHCR_IO_IMAGE_NAME}@${digest} - if [[ ${BUILDX_PLATFORMS} != *"${platform}"* ]] ; then - echo "=====================================" - echo "Ignore image for non-runnable platform ${platform}" - echo " ${image}" - echo "=====================================" - continue - fi - echo "=====================================" - echo "Inspect image for platform ${platform}" - echo " ${image}" - echo "=====================================" - docker run --rm --platform ${platform} --entrypoint sh ${image} -c \ - 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator' - done - else - echo Not a multi-arhitecture image. - #echo $(echo -n "${manifests}" | openssl dgst -sha256) ' linux/amd64' - fi + run: "# Image for one arhitecture has digest in config field.\n# Image with multiple manifests has digest in each manifest.\nmanifests=$(docker buildx imagetools inspect \"${GHCR_IO_IMAGE_NAME}\" --raw)\nif grep manifests <<<\"${manifests}\" 2>&1 >/dev/null ; then\n jq -r '.manifests[]? | .digest + \" \" + .platform.os + \"/\" + .platform.architecture' <<<\"${manifests}\" \\\n | while read digest platform ; do\n image=${GHCR_IO_IMAGE_NAME}@${digest}\n if [[ ${BUILDX_PLATFORMS} != *\"${platform}\"* ]] ; then\n echo \"=====================================\"\n echo \"Ignore image for non-runnable platform ${platform}\"\n echo \" ${image}\"\n echo \"=====================================\"\n continue \n fi\n echo \"=====================================\"\n echo \"Inspect image for platform ${platform}\"\n echo \" ${image}\"\n echo \"=====================================\"\n docker run --rm --platform ${platform} --entrypoint sh ${image} -c \\\n 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator'\n done\nelse\n echo Not a multi-arhitecture image.\n #echo $(echo -n \"${manifests}\" | openssl dgst -sha256) ' linux/amd64'\nfi\n" diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index d573fda8..ed8c3c21 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -2,18 +2,15 @@ # Build tag from release name when release is published. # Build 'latest' tag when release is published and marked as 'latest'. name: Publish release image - on: workflow_dispatch: release: types: [published] - env: QEMU_PLATFORMS: arm64,arm BUILDX_PLATFORMS: "linux/amd64,linux/arm64,linux/arm/v7" DOCKER_HUB_REPO: flant/shell-operator GHCR_IO_REPO: ghcr.io/flant/shell-operator - jobs: check: name: Check @@ -73,7 +70,6 @@ jobs: core.setOutput('run_publish', runPublish.toString()); core.setOutput('image_tag', imageTag); core.setOutput('additional_tag', additionalTag); - publish_image: name: Build and publish runs-on: [ubuntu-latest] @@ -82,7 +78,6 @@ jobs: if: needs.check.outputs.run_publish == 'true' steps: - uses: actions/checkout@v4 - - name: Prepare environment env: ADDITIONAL_TAG: ${{ needs.check.outputs.additional_tag }} @@ -116,25 +111,21 @@ jobs: echo "ADDITIONAL_DOCKER_HUB_IMAGE_NAME = $ADDITIONAL_DOCKER_HUB_IMAGE_NAME" && \ echo "ADDITIONAL_GHCR_IO_IMAGE_NAME = $ADDITIONAL_GHCR_IO_IMAGE_NAME" echo "=========================================" - - name: Set up QEMU uses: docker/setup-qemu-action@v3.6.0 with: platforms: "${{ env.QEMU_PLATFORMS }}" - - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 with: version: latest - - name: Login to Github Container Registry uses: docker/login-action@v3.4.0 with: registry: ghcr.io username: ${{ secrets.GHCR_IO_USER }} password: ${{ secrets.GHCR_IO_PASS }} - - name: Build and push multi-arch image run: | echo "Build and push $FINAL_IMAGE_NAME with version '$APP_VERSION'." @@ -147,45 +138,19 @@ jobs: --tag $GHCR_IO_IMAGE_NAME \ --push \ . - - name: Inspect binaries - run: | - # Image for one arhitecture has digest in config field. - # Image with multiple manifests has digest in each manifest. - manifests=$(docker buildx imagetools inspect "${GHCR_IO_IMAGE_NAME}" --raw) - if grep manifests <<<"${manifests}" 2>&1 >/dev/null ; then - jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" - else - echo $(echo -n "${manifests}" | openssl dgst -sha256 | sed s/^.stdin.*\ //) ' linux/amd64' - fi \ - | while read digest platform ; do - if [[ ${BUILDX_PLATFORMS} != *"${platform}"* ]] ; then - echo "=====================================" - echo "Ignore image for non-runnable platform ${platform}" - echo " ${image}" - echo "=====================================" - continue - fi - image=${GHCR_IO_IMAGE_NAME}@${digest} - echo "=====================================" - echo "Inspect image for platform ${platform}" - echo " ${image}" - echo "=====================================" - docker run --rm --platform ${platform} --entrypoint sh ${image} -c \ - 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator' - done - + run: "# Image for one arhitecture has digest in config field.\n# Image with multiple manifests has digest in each manifest.\nmanifests=$(docker buildx imagetools inspect \"${GHCR_IO_IMAGE_NAME}\" --raw)\nif grep manifests <<<\"${manifests}\" 2>&1 >/dev/null ; then\n jq -r '.manifests[]? | .digest + \" \" + .platform.os + \"/\" + .platform.architecture' <<<\"${manifests}\"\nelse\n echo $(echo -n \"${manifests}\" | openssl dgst -sha256 | sed s/^.stdin.*\\ //) ' linux/amd64'\nfi \\\n| while read digest platform ; do\n if [[ ${BUILDX_PLATFORMS} != *\"${platform}\"* ]] ; then\n echo \"=====================================\"\n echo \"Ignore image for non-runnable platform ${platform}\"\n echo \" ${image}\"\n echo \"=====================================\"\n continue \n fi\n image=${GHCR_IO_IMAGE_NAME}@${digest}\n echo \"=====================================\"\n echo \"Inspect image for platform ${platform}\"\n echo \" ${image}\"\n echo \"=====================================\"\n docker run --rm --platform ${platform} --entrypoint sh ${image} -c \\\n 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator'\ndone\n" - name: Copy image to Docker Hub env: DOCKER_USER: ${{ secrets.DOCKER_USER }} DOCKER_PASS: ${{ secrets.DOCKER_PASS }} run: | echo "Download crane tool ..." - + CRANE_VERSION=$(curl -s "https://api.github.com/repos/google/go-containerregistry/releases/latest" | jq -r '.tag_name') CRANE_OS=Linux # or Darwin, Windows CRANE_ARCH=x86_64 # or arm64, x86_64, armv6, i386, s390x, riscv64 - + echo "Crane version: ${CRANE_VERSION}, OS: ${CRANE_OS}, ARCH: ${CRANE_ARCH}" curl -sL "https://github.com/google/go-containerregistry/releases/download/${CRANE_VERSION}/go-containerregistry_${CRANE_OS}_${CRANE_ARCH}.tar.gz" > go-containerregistry.tar.gz echo "Extract crane tool ..." diff --git a/.github/workflows/tests-labeled.yaml b/.github/workflows/tests-labeled.yaml index bcba88c4..d5c778af 100644 --- a/.github/workflows/tests-labeled.yaml +++ b/.github/workflows/tests-labeled.yaml @@ -36,7 +36,6 @@ jobs: } catch (e) { console.log(`Error occurred while remove label. Possibly label is already removed. Ignore '${typeof e}' error.`); } - integration_tests: name: Integration tests needs: @@ -63,14 +62,12 @@ jobs: cluster_name: "kube-1-32" runs-on: ubuntu-latest steps: - - name: Set up Go 1.23 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.23" - + go-version: "1.25.5" - name: Check out shell-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4.2.3 @@ -80,27 +77,23 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Install ginkgo run: | - go install github.com/onsi/ginkgo/v2/ginkgo@latest + go install github.com/onsi/ginkgo/v2/ginkgo@v2.27.5 echo $PATH ls -la $GOPATH/bin ginkgo version - - name: Start kind cluster uses: engineerd/setup-kind@v0.6.2 with: version: "v0.27.0" image: ${{ matrix.kind_node_image }} name: ${{ matrix.cluster_name }} - - name: Run integration tests env: CLUSTER_NAME: ${{ matrix.cluster_name }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e1659f66..4d28733d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,14 +9,12 @@ jobs: name: Run unit tests runs-on: ubuntu-latest steps: - - name: Set up Go 1.23 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.23" - + go-version: "1.25.5" - name: Check out shell-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4.2.3 @@ -26,13 +24,11 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Run unit tests run: | export GOOS=linux diff --git a/.gitignore b/.gitignore index 6b60f726..a1b954bc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ *.so *.dylib +bin/ + # Test binary, build with `go test -c` *.test diff --git a/Dockerfile b/Dockerfile index 31c283d7..8ab27f29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,6 +36,7 @@ RUN GOOS=linux \ FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.23 ARG TARGETPLATFORM +ARG kubectlVersion=v1.32.10 # Install runtime dependencies RUN apk --no-cache add \ @@ -47,8 +48,8 @@ RUN apk --no-cache add \ # Determine kubectl architecture and download RUN kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ - echo "Downloading kubectl for ${kubectlArch}" && \ - wget https://dl.k8s.io/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ + echo "Downloading kubectl version ${kubectlVersion} for ${kubectlArch}" && \ + wget https://dl.k8s.io/release/${kubectlVersion}/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ chmod +x /bin/kubectl # Create hooks directory diff --git a/Makefile b/Makefile index 3e1f8be7..05a2a08b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,71 @@ + +.PHONY: go-module-version +go-module-version: go-check git-check + @echo "go get $(shell $(GO) list ./cmd/shell-operator)@$(shell $(GIT) rev-parse HEAD)" + +.PHONY: lint +lint: golangci-lint ## Run linter. + @$(GOLANGCI_LINT) run --fix + +.PHONY: test +test: go-check + @$(GO) test --race --cover ./... + +## Run all generate-* jobs in bulk. +.PHONY: generate +generate: update-k8s-version update-workflows-go-version update-workflows-golangci-lint-version update-workflows-ginkgo-version + + +##@ Dependencies + +WHOAMI ?= $(shell whoami) + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries GO=$(shell which go) GIT=$(shell which git) +GOLANGCI_LINT = $(LOCALBIN)/golangci-lint +YQ = $(LOCALBIN)/yq + +## TODO: remap in yaml file (version.yaml or smthng) +## Tool Versions +# GO_BUILDER_VERSION must be without 'v' prefix +GO_BUILDER_VERSION = 1.25.5 +GOLANGCI_LINT_VERSION = v2.8.0 +YQ_VERSION ?= v4.50.1 + + +.PHONY: update-k8s-version +update-k8s-version: go-check + @kubernetesVer=$(shell $(GO) list -m k8s.io/api | cut -d' ' -f 2); \ + kubectlVer=$$(echo $$kubernetesVer | sed 's/v0/v1/'); \ + echo "Updating kubectl version in Dockerfile to match k8s.io/api version: $$kubectlVer"; \ + sed -i "s/ARG kubectlVersion=.*/ARG kubectlVersion=$$kubectlVer/" Dockerfile; \ + echo "kubectl version in Dockerfile updated to: $$kubectlVer" + +.PHONY: update-workflows-go-version +update-workflows-go-version: yq + for file in $$(find .github/workflows -name "*.yaml"); do \ + $(YQ) -i '(.jobs[]?.steps[]? | select(.uses | test("actions/setup-go")) | .with."go-version") = "$(GO_BUILDER_VERSION)"' $$file; \ + done + echo "Updated go-version in workflow files to $(GO_BUILDER_VERSION)" + +.PHONY: update-workflows-golangci-lint-version +update-workflows-golangci-lint-version: yq + $(YQ) -i '(.jobs.run_linter.steps[] | select(.name == "Run golangci-lint") | .run) |= sub("v\\d+\\.\\d+\\.\\d+", "$(GOLANGCI_LINT_VERSION)")' .github/workflows/lint.yaml + echo "Updated golangci-lint version in lint.yaml to $(GOLANGCI_LINT_VERSION)" + +.PHONY: update-workflows-ginkgo-version +update-workflows-ginkgo-version: yq + @ginkgoVer=$(shell $(GO) list -m github.com/onsi/ginkgo/v2 | cut -d' ' -f 2); \ + $(YQ) -i '(.jobs.integration_tests.steps[] | select(.name == "Install ginkgo") | .run) |= sub("@latest", "@$$ginkgoVer")' .github/workflows/tests-labeled.yaml; \ + echo "Updated ginkgo version in tests-labeled.yaml to $$ginkgoVer" + +## Installed tools check .PHONY: go-check go-check: @@ -9,13 +75,35 @@ go-check: git-check: $(call error-if-empty,$(GIT),git) -.PHONY: go-module-version -go-module-version: go-check git-check - @echo "go get $(shell $(GO) list ./cmd/shell-operator)@$(shell $(GIT) rev-parse HEAD)" +## Tool installations + +.PHONY: golangci-lint +golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. +$(GOLANGCI_LINT): $(LOCALBIN) + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) + +.PHONY: yq +yq: $(YQ) ## Download yq locally if necessary. +$(YQ): $(LOCALBIN) + $(call go-install-tool,$(YQ),github.com/mikefarah/yq/v4,$(YQ_VERSION)) + + +# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist +# $1 - target path with name of binary +# $2 - package url which can be installed +# $3 - specific version of package +define go-install-tool +@[ -f "$(1)-$(3)" ] || { \ +set -e; \ +package=$(2)@$(3) ;\ +echo "Downloading $${package}" ;\ +rm -f $(1) || true ;\ +GOBIN=$(LOCALBIN) GOTOOLCHAIN=$(GO_TOOLCHAIN_AUTOINSTALL_VERSION) go install $${package} ;\ +mv $(1) $(1)-$(3) ;\ +} ;\ +ln -sf $(1)-$(3) $(1) +endef -.PHONY: test -test: go-check - @$(GO) test --race --cover ./... define error-if-empty @if [[ -z $(1) ]]; then echo "$(2) not installed"; false; fi diff --git a/pkg/config/config.go b/pkg/config/config.go index d26cd88b..7109881d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -79,27 +79,33 @@ func (c *Config) List() []map[string]string { c.m.Lock() defer c.m.Unlock() - res := make([]map[string]string, 0) + res := make([]map[string]string, 0, len(c.params)) for paramName, param := range c.params { paramValue := c.value(paramName) + paramInfo := map[string]string{ "name": paramName, "description": param.description, "default": param.defaultValue, "value": paramValue, } + if tempValue, ok := c.temporalValues[paramName]; ok { paramInfo["expireAt"] = tempValue.expire.Format(time.RFC3339) } + lastError := c.errors[paramName] if lastError != nil { paramInfo["lastError"] = lastError.Error() } + res = append(res, paramInfo) } + sort.SliceStable(res, func(i, j int) bool { return res[i]["name"] < res[j]["name"] }) + return res } diff --git a/pkg/hook/controller/kubernetes_bindings_controller.go b/pkg/hook/controller/kubernetes_bindings_controller.go index 97f500a0..736fe6c3 100644 --- a/pkg/hook/controller/kubernetes_bindings_controller.go +++ b/pkg/hook/controller/kubernetes_bindings_controller.go @@ -245,7 +245,7 @@ func (c *kubernetesBindingsController) HandleEvent(_ context.Context, kubeEvent } func (c *kubernetesBindingsController) BindingNames() []string { - names := []string{} + names := make([]string, 0, len(c.KubernetesBindings)) for _, binding := range c.KubernetesBindings { names = append(names, binding.BindingName) } diff --git a/pkg/kube_events_manager/resource_informer.go b/pkg/kube_events_manager/resource_informer.go index 8fc8e511..f9baa810 100644 --- a/pkg/kube_events_manager/resource_informer.go +++ b/pkg/kube_events_manager/resource_informer.go @@ -155,7 +155,7 @@ func (ei *resourceInformer) createSharedInformer() error { // Snapshot returns all cached objects for this informer func (ei *resourceInformer) getCachedObjects() []kemtypes.ObjectAndFilterResult { ei.cacheLock.RLock() - res := make([]kemtypes.ObjectAndFilterResult, 0) + res := make([]kemtypes.ObjectAndFilterResult, 0, len(ei.cachedObjects)) for _, obj := range ei.cachedObjects { res = append(res, *obj) } diff --git a/pkg/shell-operator/operator.go b/pkg/shell-operator/operator.go index 66be054b..3c7d28f5 100644 --- a/pkg/shell-operator/operator.go +++ b/pkg/shell-operator/operator.go @@ -231,7 +231,7 @@ func (op *ShellOperator) initValidatingWebhookManager() error { hookNamesV, _ := op.HookManager.GetHooksInOrder(types.KubernetesValidating) hookNamesM, _ := op.HookManager.GetHooksInOrder(types.KubernetesMutating) - var hookNames []string + hookNames := make([]string, 0, len(hookNamesV)+len(hookNamesM)) hookNames = append(hookNames, hookNamesV...) hookNames = append(hookNames, hookNamesM...) diff --git a/pkg/utils/labels/labels.go b/pkg/utils/labels/labels.go index 47dabd52..c16b6f7d 100644 --- a/pkg/utils/labels/labels.go +++ b/pkg/utils/labels/labels.go @@ -34,7 +34,7 @@ func EnrichLoggerWithLabels(logger *log.Logger, labelsMaps ...map[string]string) // LabelNames returns sorted label keys func LabelNames(labels map[string]string) []string { - names := make([]string, 0) + names := make([]string, 0, len(labels)) for labelName := range labels { names = append(names, labelName) } @@ -43,7 +43,7 @@ func LabelNames(labels map[string]string) []string { } func LabelValues(labels map[string]string, labelNames []string) []string { - values := make([]string, 0) + values := make([]string, 0, len(labelNames)) for _, name := range labelNames { values = append(values, labels[name]) } diff --git a/test/utils/prometheus.go b/test/utils/prometheus.go index 3fa15414..a59c3bb5 100644 --- a/test/utils/prometheus.go +++ b/test/utils/prometheus.go @@ -21,7 +21,7 @@ type PromMetricValue struct { } func (pmv PromMetricValue) String() string { - labels := []string{} + labels := make([]string, 0, len(pmv.Labels)) for k, v := range pmv.Labels { labels = append(labels, fmt.Sprintf("%s=%s", k, v)) }