From 0d454a35093f95f44afb59a3b9543b2233d32598 Mon Sep 17 00:00:00 2001 From: Tibi <110664232+TiberiuGC@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:15:49 +0300 Subject: [PATCH] Automatically update coredns assets using Github workflows (#7178) * Automatically update coredns assets using github workflows * configure aws credentials * add id-token permission * update role duration value to minimum supported * fix typo --- .github/workflows/update-generated.yaml | 32 +++++-- Makefile | 4 + .../default/scripts/update_coredns_assets.go | 92 +++++++++++++++++++ 3 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 pkg/addons/default/scripts/update_coredns_assets.go diff --git a/.github/workflows/update-generated.yaml b/.github/workflows/update-generated.yaml index 601615753f..b0de3a0acb 100644 --- a/.github/workflows/update-generated.yaml +++ b/.github/workflows/update-generated.yaml @@ -4,13 +4,19 @@ on: schedule: - cron: "0 5 * * Thu" +permissions: + id-token: write + env: DEFAULT_BRANCH: main - UPDATE_BRANCH: update-aws-node jobs: - update_aws_node: - name: Update aws-node and open PR + update_generated_file: + strategy: + fail-fast: false + matrix: + resource: ["coredns", "aws-node"] + name: Update ${{ matrix.resource }} and open PR runs-on: ubuntu-latest container: public.ecr.aws/eksctl/eksctl-build:516ded83aa5dbd3e3c4e25c5d410e2dba3b5e668 env: @@ -21,6 +27,14 @@ jobs: with: token: ${{ secrets.EKSCTLBOT_TOKEN }} fetch-depth: 0 + - name: Configure AWS credentials for coredns update + if: ${{ matrix.resource == 'coredns' }} + uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 + with: + aws-region: us-west-2 + role-duration-seconds: 900 + role-session-name: eksctl-update-coredns-assets + role-to-assume: ${{ secrets.UPDATE_COREDNS_ROLE_ARN }} - name: Setup identity as eksctl-bot uses: ./.github/actions/setup-identity with: @@ -34,15 +48,15 @@ jobs: key: go-${{ hashFiles('go.sum') }} restore-keys: | go- - - name: Update aws-node - run: make update-aws-node + - name: Update ${{ matrix.resource }} + run: make update-${{ matrix.resource }} - name: Commit changes id: commit run: | git checkout $DEFAULT_BRANCH - git checkout -B $UPDATE_BRANCH + git checkout -B update-${{ matrix.resource }} git add -u - if ! EDITOR=true git commit -m "Update aws-node"; then + if ! EDITOR=true git commit -m "Update ${{ matrix.resource }}"; then echo "changes=false" >> $GITHUB_OUTPUT exit 0 fi @@ -57,8 +71,8 @@ jobs: script: | const { data: pr } = await github.rest.pulls.create({ ...context.repo, - title: "Update aws-node", - head: "${{ env.UPDATE_BRANCH }}", + title: "Update ${{ matrix.resource }}", + head: "update-${{ matrix.resource }}", base: "${{ env.DEFAULT_BRANCH }}", }); await github.rest.issues.addLabels({ diff --git a/Makefile b/Makefile index acafc8ca58..659911ab4d 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,10 @@ pkg/addons/default/assets/aws-node.yaml: update-aws-node: ## Re-download the aws-node manifests from AWS go generate ./pkg/addons/default/aws_node_generate.go +.PHONY: +update-coredns: ## get latest coredns builds for each available eks version + @go run pkg/addons/default/scripts/update_coredns_assets.go + deep_copy_helper_input = $(shell $(call godeps_cmd,./pkg/apis/...) | sed 's|$(generated_code_deep_copy_helper)||' ) $(generated_code_deep_copy_helper): $(deep_copy_helper_input) ## Generate Kubernetes API helpers build/scripts/update-codegen.sh diff --git a/pkg/addons/default/scripts/update_coredns_assets.go b/pkg/addons/default/scripts/update_coredns_assets.go new file mode 100644 index 0000000000..3976c4d323 --- /dev/null +++ b/pkg/addons/default/scripts/update_coredns_assets.go @@ -0,0 +1,92 @@ +package main + +import ( + "context" + "fmt" + "log" + "os" + "path/filepath" + "regexp" + "sort" + "strings" + + "github.com/aws/aws-sdk-go-v2/aws" + awseks "github.com/aws/aws-sdk-go-v2/service/eks" + "github.com/blang/semver" + + api "github.com/weaveworks/eksctl/pkg/apis/eksctl.io/v1alpha5" + "github.com/weaveworks/eksctl/pkg/eks" +) + +func main() { + ctx := context.Background() + + clusterProvider, err := eks.New(ctx, &api.ProviderConfig{}, nil) + if err != nil { + log.Fatalf("failed to create the AWS provider: %v", err) + } + + for _, kubernetesVersion := range api.SupportedVersions() { + latestVersion := getLatestVersion(ctx, clusterProvider, kubernetesVersion) + if latestVersion == "" { + continue + } + replaceCurrentVersionIfOutdated(latestVersion, kubernetesVersion) + } + +} + +func getLatestVersion(ctx context.Context, clusterProvider *eks.ClusterProvider, kubernetesVersion string) string { + output, err := clusterProvider.AWSProvider.EKS().DescribeAddonVersions(ctx, &awseks.DescribeAddonVersionsInput{ + AddonName: aws.String("coredns"), + KubernetesVersion: &kubernetesVersion, + }) + if err != nil { + log.Fatalf("failed calling EKS::DescribeAddonVersions: %v", err) + } + + corednsVersions := output.Addons[0].AddonVersions + if len(corednsVersions) == 0 { + return "" + } + + sort.Slice(corednsVersions, func(i, j int) bool { + vi, err := semver.Parse(trim(*corednsVersions[i].AddonVersion)) + if err != nil { + log.Fatalf("failed to parse coredns version %s: %v", trim(*corednsVersions[i].AddonVersion), err) + } + vj, err := semver.Parse(trim(*corednsVersions[j].AddonVersion)) + if err != nil { + log.Fatalf("failed to parse coredns version %s: %v", trim(*corednsVersions[j].AddonVersion), err) + } + if vi.Compare(vj) >= 0 { + return true + } + return false + }) + + return *corednsVersions[0].AddonVersion +} + +func replaceCurrentVersionIfOutdated(latestVersion string, kubernetesVersion string) { + filePath := filepath.Join("pkg", "addons", "default", "assets", fmt.Sprintf("coredns-%s.json", kubernetesVersion)) + coreFile, err := os.ReadFile(filePath) + if err != nil { + log.Fatalf("failed to read coredns-%s.json: %v", kubernetesVersion, err) + } + + regexpVersion := regexp.MustCompile(`v\d+\.\d+\.\d+-eksbuild\.\d+`) + currentVersion := regexpVersion.FindString(string(coreFile)) + if currentVersion == "" { + log.Fatalf("couldn't find coredns version in coredns-%s.json", kubernetesVersion) + } + + updatedCoreFile := regexpVersion.ReplaceAllString(string(coreFile), latestVersion) + if err := os.WriteFile(filePath, []byte(updatedCoreFile), 0644); err != nil { + log.Fatalf("failed to write coredns-%s.json: %v", kubernetesVersion, err) + } +} + +func trim(version string) string { + return strings.TrimPrefix(version, "v") +}