From 8f518a324d198afda17f8e8a1ec59c8daf3a74a1 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 2 Jul 2024 12:55:54 -0700 Subject: [PATCH 1/2] Add GitHub workflow for acceptance tests Remove Pipelines config file --- .github/workflows/acceptance-tests.yml | 170 +++++++++++++++++++++++++ .jfrog-pipelines/pipeline.yml | 121 ------------------ README.md | 2 + scripts/system.yaml | 17 +++ 4 files changed, 189 insertions(+), 121 deletions(-) create mode 100644 .github/workflows/acceptance-tests.yml delete mode 100644 .jfrog-pipelines/pipeline.yml create mode 100755 scripts/system.yaml diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml new file mode 100644 index 0000000..d9dfd6e --- /dev/null +++ b/.github/workflows/acceptance-tests.yml @@ -0,0 +1,170 @@ +on: + pull_request: + branches: + - master + types: [opened,synchronize] + paths: + - '**.go' + workflow_dispatch: + +name: Vault Acceptance Tests + +jobs: + acceptance-tests: + runs-on: ubuntu-latest + continue-on-error: false + environment: development + outputs: + vault_version: ${{ steps.get_vault_cli_version.outputs.version }} + artifactory_version: ${{ steps.run_artifactory_container.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Unshallow + run: git fetch --prune --unshallow + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.21 + - name: Install Helm + uses: azure/setup-helm@v4.2.0 + - name: Install Vault CLI + uses: eLco/setup-vault@v1 + - name: Get Vault CLI version + id: get_vault_cli_version + run: | + VAULT_VERSION=$(vault version | grep -o -E "v\d+\.\d+\.\d+") + echo "version=$VAULT_VERSION" >> "$GITHUB_OUTPUT" + - name: Install GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + install-only: true + - name: Create Artifactory data directories and copy data + env: + ARTIFACTORY_LICENSE: ${{ secrets.ARTIFACTORY_LICENSE }} + run: | + mkdir -p ${{ runner.temp }}/artifactory/extra_conf + mkdir -p ${{ runner.temp }}/artifactory/var/etc + echo $ARTIFACTORY_LICENSE > ${{ runner.temp }}/artifactory/extra_conf/artifactory.lic + cp ${{ github.workspace }}/scripts/system.yaml ${{ runner.temp }}/artifactory/var/etc/system.yaml + sudo chown -R 1030:1030 ${{ runner.temp }}/artifactory/var + - name: Run Artifactory container + id: run_artifactory_container + run: | + echo "Get latest Artifactory image tag" + helm repo add artifactory https://charts.jfrog.io + helm repo update + ARTIFACTORY_VERSION=$(helm search repo | grep "artifactory " | awk '{$1=$1};1' | cut -f3 -d " ") + echo "version=$ARTIFACTORY_VERSION" >> "$GITHUB_OUTPUT" + echo "Start up Artifactory container" + docker run -i --name artifactory -d --rm \ + -v ${{ runner.temp }}/artifactory/extra_conf:/artifactory_extra_conf \ + -v ${{ runner.temp }}/artifactory/var:/var/opt/jfrog/artifactory \ + -p 8081:8081 -p 8082:8082 \ + releases-docker.jfrog.io/jfrog/artifactory-pro:${ARTIFACTORY_VERSION} + echo "Set localhost to a container IP address, since we run docker inside of docker" + export LOCALHOST=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.Gateway}}{{end}}' artifactory) + export JFROG_URL="http://${LOCALHOST}:8082" + echo "JFROG_URL=$JFROG_URL" >> "$GITHUB_ENV" + echo "Waiting for Artifactory services to start at ${JFROG_URL}" + until $(curl -sf -o /dev/null -m 5 ${JFROG_URL}/artifactory/api/system/ping/); do + printf '.' + sleep 5 + done + echo "Waiting for Artifactory UI to start" + until $(curl -sf -o /dev/null -m 5 ${JFROG_URL}/ui/login/); do + printf '.' + sleep 5 + done + export COOKIES=$(curl -s -c - "${JFROG_URL}/ui/api/v1/ui/auth/login?_spring_security_remember_me=false" \ + --header "accept: application/json, text/plain, */*" \ + --header "content-type: application/json;charset=UTF-8" \ + --header "x-requested-with: XMLHttpRequest" \ + -d '{"user":"admin","password":"'"${{ secrets.ARTIFACTORY_PASSWORD }}"'","type":"login"}' | grep FALSE) + export REFRESHTOKEN=$(echo $COOKIES | grep REFRESHTOKEN | awk '{print $7}') + export ACCESSTOKEN=$(echo $COOKIES | grep ACCESSTOKEN | awk '{print $14}') + export JFROG_ACCESS_TOKEN=$(curl -s -g --request GET "${JFROG_URL}/ui/api/v1/system/security/token?services[]=all" \ + --header "accept: application/json, text/plain, */*" \ + --header "x-requested-with: XMLHttpRequest" \ + --header "cookie: ACCESSTOKEN=${ACCESSTOKEN}; REFRESHTOKEN=${REFRESHTOKEN}") + echo "::add-mask::$JFROG_ACCESS_TOKEN" + echo "JFROG_ACCESS_TOKEN=$JFROG_ACCESS_TOKEN" >> "$GITHUB_ENV" + - name: Execute acceptance tests + run: make acceptance + - name: Clean up Docker container + if: always() && ${{ steps.run_artifactory_container.outcome == 'success' }} + run: docker stop artifactory + - name: Send workflow status to Slack + uses: slackapi/slack-github-action@v1.26.0 + if: always() + with: + payload: | + { + "text": "${{ github.workflow }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }} ${{ matrix.cli }} GitHub Action result: ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ github.workflow }} : ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PR_WEBHOOK }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + update-changelog: + runs-on: ubuntu-latest + needs: acceptance-tests + if: ${{ github.event_name == 'pull_request' }} && ${{ needs.acceptance-tests.result == 'success' }} + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.ref }} + - name: Update CHANGELOG and push commit + env: + ARTIFACTORY_VERSION: ${{ needs.acceptance-tests.outputs.artifactory_version }} + VAULT_VERSION: ${{ needs.acceptance-tests.outputs.vault_version }} + run: | + echo "Adding Artifactory version to CHANGELOG.md" + sed -i -E "0,/(##\s.+\..+\..+\s\(.+\)).*/ s/(##\s.+\..+\..+\s\(.+\)).*/\1. Tested on Artifactory $ARTIFACTORY_VERSION with Vault $VAULT_VERSION/" CHANGELOG.md + head -10 CHANGELOG.md + git add CHANGELOG.md + export REGEX="Changes to be committed*" + export GIT_STATUS=$(git status) + if [[ ${GIT_STATUS} =~ ${REGEX} ]]; then + echo "Commiting changes" + git config --global user.name 'JFrog CI' + git config --global user.email 'jfrog-solutions-ci+1@jfrog.com' + git config --get user.name + git config --get user.email + git commit --author="JFrog CI " -m "JFrog Pipelines - Add Artifactory version to CHANGELOG.md" + git push + else + echo "There is nothing to commit: Artifactory version hadn't changed." + fi + - name: Send workflow status to Slack + uses: slackapi/slack-github-action@v1.26.0 + if: success() + with: + payload: | + { + "text": "Terraform Provider Platform. A new PR was submitted by ${{ github.event.pull_request.user.login }} - ${{ github.event.pull_request.html_url }}, branch ${{ github.event.pull_request.base.ref }}. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge.", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ". A new PR was submitted by *${{ github.event.pull_request.user.login }}* - <${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>, branch *${{ github.event.pull_request.base.ref }}*. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge." + } + } + ] + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PR_WEBHOOK }} + SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/.jfrog-pipelines/pipeline.yml b/.jfrog-pipelines/pipeline.yml deleted file mode 100644 index a70fcb7..0000000 --- a/.jfrog-pipelines/pipeline.yml +++ /dev/null @@ -1,121 +0,0 @@ -resources: - - name: GitHubVaultPluginRepoJFrog - type: GitRepo - configuration: - gitProvider: partnership_github - path: {{.jfrog-pipelines.sourceRepository}} - branches: - include: master - buildOn: - commit: true - pullRequestCreate: true - cancelPendingRunsOn: - pullRequestUpdate: true -pipelines: - - name: vault_plugin_artifactory - steps: - - name: build_and_test_vault_plugin - type: Bash - configuration: - priority: 1 - timeoutSeconds: 600 # 10 minutes - runtime: - type: image - image: - auto: - language: go - versions: - - "1.21" - requiresApproval: - approvers: - - alexh - - danielmi - notifications: - - integrationName: partnership_slack - timeoutSeconds: 172800 # 2 days - integrations: - - name: partnership_slack - - name: partnership_github - - name: partnership_rt_cluster_license - inputResources: - - name: GitHubVaultPluginRepoJFrog - execution: - onStart: - - cd ${res_GitHubVaultPluginRepoJFrog_resourcePath} # we need to manually move into the resource path - - echo "Pending" - - export STATE="pending" - - export DESCRIPTION="Pipeline run is in progress." - - ./scripts/github-status.sh ${res_GitHubVaultPluginRepoJFrog_gitProvider_token} ${res_GitHubVaultPluginRepoJFrog_gitRepoFullName} ${res_GitHubVaultPluginRepoJFrog_commitSha} - - echo "Install GoReleaser" - - echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list - - sudo apt update - - sudo apt install goreleaser - - ls -al && pwd - - echo "Helm 3 install" - - curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 && chmod 700 get_helm.sh - - echo "Run Helm installation script" && ./get_helm.sh && rm get_helm.sh - - helm version - - printenv - onExecute: - - echo "Verify the code contents merged feature branch with master branch (detached mode)" - - git branch && ls -al - - add_run_variables PLUGIN_VERSION=$(git describe --tags --abbrev=0 | sed -n 's/v\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1.\2.\3/p') - - export NEXT_VERSION=${PLUGIN_VERSION} && echo ${NEXT_VERSION} - - echo "Save RT licenses from the variable to the license file" - - echo ${int_partnership_rt_cluster_license_5licenses} > scripts/artifactory.lic - - more scripts/artifactory.lic - - echo "Set Artifactory version, run RT in a container" - - helm repo add artifactory https://charts.jfrog.io - - helm repo update - - add_run_variables ARTIFACTORY_VERSION=$(helm search repo | grep "artifactory " | awk '{$1=$1};1' | cut -f3 -d " ") - - echo "Artifactory version ${ARTIFACTORY_VERSION}" - - export ARTIFACTORY_CONTAINER_NAME=artifactory - - >- - docker run -i --name ${ARTIFACTORY_CONTAINER_NAME} -t -d --rm -v "${res_GitHubVaultPluginRepoJFrog_resourcePath}/scripts/artifactory.lic:/artifactory_extra_conf/artifactory.lic:ro" \ - -p8081:8081 -p8082:8082 -p8080:8080 releases-docker.jfrog.io/jfrog/artifactory-pro:${ARTIFACTORY_VERSION} - - echo "Set localhost to a container IP address, since we run docker inside of docker" - - export LOCALHOST=$(docker inspect -f '{{`{{range.NetworkSettings.Networks}}{{.Gateway}}{{end}}`}}' ${ARTIFACTORY_CONTAINER_NAME}) - - echo "Using ${LOCALHOST} as 'localhost' ip address" - - echo "Waiting for Artifactory to start (doesn't reflect the start of the UI!)" - - >- - until curl -sf -u admin:password http://${LOCALHOST}:8081/artifactory/api/system/licenses/; do - printf '.' - sleep 4 - done - - echo "Add variables needed to run Terraform Provider" - - export JFROG_URL="http://${LOCALHOST}:8082" - - echo "Get cookie to generate Access token. We need a pause to let UI come up to get cookies" - - >- - until curl -sf -o /dev/null -u admin:password ${JFROG_URL}/ui/login/; do - printf '.' > /dev/stderr - sleep 4 - done - - sudo curl http://${LOCALHOST}:8082/router/api/v1/system/health - - >- - export COOKIES=$(curl -c - "${JFROG_URL}/ui/api/v1/ui/auth/login?_spring_security_remember_me=false" \ - --header "accept: application/json, text/plain, */*" \ - --header "content-type: application/json;charset=UTF-8" \ - --header "x-requested-with: XMLHttpRequest" \ - -d '{"user":"admin","password":"'"password"'","type":"login"}' | grep FALSE) - - export REFRESHTOKEN=$(echo $COOKIES | grep REFRESHTOKEN | awk '{print $7}') - - export ACCESSTOKEN=$(echo $COOKIES | grep ACCESSTOKEN | awk '{print $14}') # awk returns null on Mac, and the actual key on Ubuntu 20 - - >- - export JFROG_ACCESS_TOKEN=$(curl -g --request GET "${JFROG_URL}/ui/api/v1/system/security/token?services[]=all" \ - --header "accept: application/json, text/plain, */*" \ - --header "x-requested-with: XMLHttpRequest" \ - --header "cookie: ACCESSTOKEN=${ACCESSTOKEN}; REFRESHTOKEN=${REFRESHTOKEN}") - - make acceptance - onSuccess: - - echo "Success" - - export STATE="success" - - export DESCRIPTION="All tests passed successfully." - - ./scripts/github-status.sh ${res_GitHubVaultPluginRepoJFrog_gitProvider_token} ${res_GitHubVaultPluginRepoJFrog_gitRepoFullName} ${res_GitHubVaultPluginRepoJFrog_commitSha} - - send_notification partnership_slack --text "${pipeline_name} step <${step_url}|${step_name}> is completed. Version ${NEXT_VERSION:-" wasn't set"}." - onFailure: - - echo "Failure" - - export STATE="failure" - - export DESCRIPTION="Pipeline has failed." - - ./scripts/github-status.sh ${res_GitHubVaultPluginRepoJFrog_gitProvider_token} ${res_GitHubVaultPluginRepoJFrog_gitRepoFullName} ${res_GitHubVaultPluginRepoJFrog_commitSha} - - send_notification partnership_slack --text "${pipeline_name} pipeline failed on <${step_url}|${step_name}> step." - onComplete: - - echo "Complete" diff --git a/README.md b/README.md index 25f07db..0b91343 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Vault Acceptance Tests](https://github.com/jfrog/vault-plugin-secrets-artifactory/actions/workflows/acceptance-tests.yml/badge.svg)](https://github.com/jfrog/vault-plugin-secrets-artifactory/actions/workflows/acceptance-tests.yml) + # Vault Artifactory Secrets Plugin This plugin is actively maintained by JFrog Inc. Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for contributions and [create GitHub issues](https://github.com/jfrog/vault-plugin-secrets-artifactory/issues/new/choose) to ask for feature requests and support. diff --git a/scripts/system.yaml b/scripts/system.yaml new file mode 100755 index 0000000..f67fdcf --- /dev/null +++ b/scripts/system.yaml @@ -0,0 +1,17 @@ +## @formatter:off +## JFROG ARTIFACTORY SYSTEM CONFIGURATION FILE +## HOW TO USE: comment-out any field and keep the correct yaml indentation by deleting only the leading '#' character. +configVersion: 1 +## NOTE: JFROG_HOME is a place holder for the JFrog root directory containing the deployed product, the home directory for all JFrog products. +## Replace JFROG_HOME with the real path! For example, in RPM install, JFROG_HOME=/opt/jfrog + +## NOTE: Sensitive information such as passwords and join key are encrypted on first read. +## NOTE: The provided commented key and value is the default. + +## SHARED CONFIGURATIONS +## A shared section for keys across all services in this config +shared: + extraJavaOpts: "-Dartifactory.policy.cleanup.package.enabled=true" + database: + ## To run Artifactory with any database other than PostgreSQL allowNonPostgresql set to true. + allowNonPostgresql: true From 562a96ddf34316cc7ec1f66fc4c375051211f098 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 2 Jul 2024 13:08:25 -0700 Subject: [PATCH 2/2] Fix slack message Update GitHub action versions for release workflow --- .github/workflows/acceptance-tests.yml | 8 ++++---- .github/workflows/release.yml | 17 +++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index d9dfd6e..13da298 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -100,13 +100,13 @@ jobs: with: payload: | { - "text": "${{ github.workflow }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }} ${{ matrix.cli }} GitHub Action result: ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}", + "text": "${{ github.workflow }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/${{ github.job }} GitHub Action result: ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": "${{ github.workflow }} : ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" + "text": "${{ github.workflow }} : ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}" } } ] @@ -154,13 +154,13 @@ jobs: with: payload: | { - "text": "Terraform Provider Platform. A new PR was submitted by ${{ github.event.pull_request.user.login }} - ${{ github.event.pull_request.html_url }}, branch ${{ github.event.pull_request.base.ref }}. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge.", + "text": "Vault Artifactory Secrets Plugin. A new PR was submitted by ${{ github.event.pull_request.user.login }} - ${{ github.event.pull_request.html_url }}, branch ${{ github.event.pull_request.base.ref }}. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge.", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", - "text": ". A new PR was submitted by *${{ github.event.pull_request.user.login }}* - <${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>, branch *${{ github.event.pull_request.base.ref }}*. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge." + "text": ". A new PR was submitted by *${{ github.event.pull_request.user.login }}* - <${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>, branch *${{ github.event.pull_request.base.ref }}*. Changes tested successfully. <@U01H1SLSPA8> or <@UNDRUL1EU> please, review and merge." } } ] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3272277..483a67a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,33 +6,30 @@ on: push: tags: - 'v*' + jobs: goreleaser: runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/tags/') && github.event.base_ref == 'refs/heads/master' steps: - name: Checkout - uses: actions/checkout@v4.1.1 - + uses: actions/checkout@v4 - name: Unshallow run: git fetch --prune --unshallow - - name: Set up Go uses: actions/setup-go@v5 with: go-version: 1.21 - - name: Import GPG key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5.0.0 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.PASSPHRASE }} - + passphrase: ${{ secrets.GPG_PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v4 + uses: goreleaser/goreleaser-action@v6 with: - version: latest + version: ${{ github.event.inputs.tag }} args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}