diff --git a/.gcloudignore b/.gcloudignore
new file mode 100644
index 00000000000..863d57bfd64
--- /dev/null
+++ b/.gcloudignore
@@ -0,0 +1,7 @@
+# By default, everything inside .gitignore (as well as the .git directory and
+# the .gitignore file itself) is not uploaded to Google Cloud Build. But the
+# bintray publishing task requires the .git directory to uploaded.
+#
+# Adding this file overrides the default, so everything gets uploaded, but we
+# still want to exclude the large .gradle cache directory.
+.gradle
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c2f1cf0970b..eee1bb58d6e 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -4,7 +4,7 @@ Please refer to [Contributing to Spinnaker](https://spinnaker.io/community/contr
When filling out a pull request, please consider the following:
-* Follow the commit message conventions [found here](http://www.spinnaker.io/v1.0/docs/how-to-submit-a-patch).
+* Follow the commit message conventions [found here](https://spinnaker.io/community/contributing/submitting/).
* Provide a descriptive summary for your changes.
* If it fixes a bug or resolves a feature request, be sure to link to that issue.
* Add inline code comments to changes that might not be obvious.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000000..f9ecf576e17
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,7 @@
+version: 2
+updates:
+ # Maintain dependencies for GitHub Actions
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000000..0dd8ac5430c
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,90 @@
+name: Branch Build
+
+on:
+ push:
+ branches:
+ - master
+ - release-*
+
+env:
+ GRADLE_OPTS: -Dorg.gradle.daemon=false -Xmx12g -Xms12g
+ CONTAINER_REGISTRY: us-docker.pkg.dev/spinnaker-community/docker
+
+jobs:
+ branch-build:
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create more disk space
+ run: sudo rm -rf /usr/share/dotnet && sudo rm -rf /opt/ghc && sudo rm -rf "/usr/local/share/boost" && sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 17
+ distribution: 'zulu'
+ cache: 'gradle'
+ - name: Prepare build variables
+ id: build_variables
+ run: |
+ echo REPO="${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT
+ echo VERSION="$(git describe --tags --abbrev=0 --match='v[0-9]*' | cut -c2-)-dev-${GITHUB_REF_NAME}-$(git rev-parse --short HEAD)-$(date --utc +'%Y%m%d%H%M')" >> $GITHUB_OUTPUT
+ - name: Build
+ env:
+ ORG_GRADLE_PROJECT_version: ${{ steps.build_variables.outputs.VERSION }}
+ run: ./gradlew build --stacktrace ${{ steps.build_variables.outputs.REPO }}-web:installDist
+ - name: Build local slim container image for testing
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.slim
+ load: true
+ platforms: local
+ tags: |
+ "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated"
+ - name: Test local slim container image
+ env:
+ FULL_DOCKER_IMAGE_NAME: "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated"
+ run: ./gradlew ${{ steps.build_variables.outputs.REPO }}-integration:test
+ - name: Login to GAR
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/login-action@v3
+ # use service account flow defined at: https://github.com/docker/login-action#service-account-based-authentication-1
+ with:
+ registry: us-docker.pkg.dev
+ username: _json_key
+ password: ${{ secrets.GAR_JSON_KEY }}
+ - name: Build and publish slim container image
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.slim
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ github.ref_name }}-latest-unvalidated"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ github.ref_name }}-latest-unvalidated-slim"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated-slim"
+ - name: Build and publish ubuntu container image
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.ubuntu
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ github.ref_name }}-latest-unvalidated-ubuntu"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated-ubuntu"
diff --git a/.github/workflows/bump_dependencies.yml b/.github/workflows/bump_dependencies.yml
new file mode 100644
index 00000000000..9a3e287d4a7
--- /dev/null
+++ b/.github/workflows/bump_dependencies.yml
@@ -0,0 +1,17 @@
+name: Bump Dependencies
+
+on:
+ repository_dispatch:
+ types: [bump-dependencies]
+
+jobs:
+ bump-dependencies:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: spinnaker/bumpdeps@master
+ with:
+ ref: ${{ github.event.client_payload.ref }}
+ key: clouddriverVersion
+ repositories: halyard
+ env:
+ GITHUB_OAUTH: ${{ secrets.SPINNAKER_GITHUB_TOKEN }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000000..538a03382d3
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,66 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ schedule:
+ - cron: '22 20 * * *'
+
+jobs:
+ analyze:
+ if: startsWith(github.repository, 'spinnaker/')
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'java' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
+ # Learn more about CodeQL language support at https://git.io/codeql-language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v3
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
new file mode 100644
index 00000000000..eb00f93cd42
--- /dev/null
+++ b/.github/workflows/gradle-wrapper-validation.yml
@@ -0,0 +1,10 @@
+name: "Validate Gradle Wrapper"
+on: [push, pull_request]
+
+jobs:
+ validation:
+ name: "Gradle wrapper validation"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: gradle/wrapper-validation-action@v3
diff --git a/.github/workflows/integration-tests-kubernetes.yml b/.github/workflows/integration-tests-kubernetes.yml
new file mode 100644
index 00000000000..7ae041ee770
--- /dev/null
+++ b/.github/workflows/integration-tests-kubernetes.yml
@@ -0,0 +1,69 @@
+name: Kubernetes Integration Tests
+
+on: workflow_call
+
+env:
+ GRADLE_OPTS: -Dorg.gradle.daemon=false -Xmx12g -Xms12g
+
+jobs:
+ it-test-kubernetes:
+ strategy:
+ matrix:
+ kubectl-version:
+ - 1.22.17
+ kubernetes-image:
+ - "kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570"
+ - "kindest/node:v1.28.0@sha256:b7a4cad12c197af3ba43202d3efe03246b3f0793f162afb40a33c923952d5b31"
+ - "kindest/node:v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72"
+ - "kindest/node:v1.26.6@sha256:6e2d8b28a5b601defe327b98bd1c2d1930b49e5d8c512e1895099e4504007adb"
+ - "kindest/node:v1.25.11@sha256:227fa11ce74ea76a0474eeefb84cb75d8dad1b08638371ecf0e86259b35be0c8"
+ - "kindest/node:v1.24.15@sha256:7db4f8bea3e14b82d12e044e25e34bd53754b7f2b0e9d56df21774e6f66a70ab"
+ - "kindest/node:v1.23.17@sha256:59c989ff8a517a93127d4a536e7014d28e235fb3529d9fba91b3951d461edfdb"
+ - "kindest/node:v1.22.17@sha256:f5b2e5698c6c9d6d0adc419c0deae21a425c07d81bbf3b6a6834042f25d4fba2"
+ - "kindest/node:v1.21.14@sha256:8a4e9bb3f415d2bb81629ce33ef9c76ba514c14d707f9797a01e3216376ba093"
+ include:
+ - kubectl-version: 1.29.1
+ kubernetes-image: "kindest/node:v1.29.0@sha256:eaa1450915475849a73a9227b8f201df25e55e268e5d619312131292e324d570"
+ - kubectl-version: 1.28.6
+ kubernetes-image: "kindest/node:v1.28.0@sha256:b7a4cad12c197af3ba43202d3efe03246b3f0793f162afb40a33c923952d5b31"
+ - kubectl-version: 1.27.10
+ kubernetes-image: "kindest/node:v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72"
+ - kubectl-version: 1.26.13
+ kubernetes-image: "kindest/node:v1.26.6@sha256:6e2d8b28a5b601defe327b98bd1c2d1930b49e5d8c512e1895099e4504007adb"
+ - kubectl-version: 1.25.16
+ kubernetes-image: "kindest/node:v1.25.11@sha256:227fa11ce74ea76a0474eeefb84cb75d8dad1b08638371ecf0e86259b35be0c8"
+ - kubectl-version: 1.24.17
+ kubernetes-image: "kindest/node:v1.24.15@sha256:7db4f8bea3e14b82d12e044e25e34bd53754b7f2b0e9d56df21774e6f66a70ab"
+ - kubectl-version: 1.23.17
+ kubernetes-image: "kindest/node:v1.23.17@sha256:59c989ff8a517a93127d4a536e7014d28e235fb3529d9fba91b3951d461edfdb"
+ - kubectl-version: 1.21.14
+ kubernetes-image: "kindest/node:v1.21.14@sha256:8a4e9bb3f415d2bb81629ce33ef9c76ba514c14d707f9797a01e3216376ba093"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 17
+ distribution: 'zulu'
+ - name: Cache on push
+ if: github.event_name == 'push'
+ uses: actions/cache@v4
+ with:
+ path: ~/.gradle
+ key: ${{ runner.os }}-cd-it-${{ github.sha }}
+ # Restore build outputs from the previous commit (if successful), if current commit hasn't run successfully yet
+ restore-keys: |
+ ${{ runner.os }}-cd-it-${{ github.event.before }}
+ - name: Cache on pull_request
+ if: github.event_name == 'pull_request'
+ uses: actions/cache@v4
+ with:
+ path: ~/.gradle
+ key: ${{ runner.os }}-cd-it-${{ github.event.pull_request.head.sha }}
+ restore-keys: |
+ ${{ runner.os }}-cd-it-${{ github.event.before }}
+ - name: Kubernetes Provider Integration Tests
+ run: |
+ version=$(echo '${{ matrix.kubernetes-image }}' | grep -o 'v[0-9]*\.[0-9]*')
+ ./gradlew --build-cache :clouddriver-kubernetes:integrationTest -Pkubernetes-image=${{ matrix.kubernetes-image }} -Pkubectl-version=${{ matrix.kubectl-version }} -Pkubernetes-version=${version}
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
new file mode 100644
index 00000000000..c3e763d3738
--- /dev/null
+++ b/.github/workflows/integration_tests.yml
@@ -0,0 +1,47 @@
+name: Integration Tests
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+env:
+ GRADLE_OPTS: -Dorg.gradle.daemon=false -Xmx4g -Xms4g
+
+jobs:
+ it-test-kubernetes:
+ uses: ./.github/workflows/integration-tests-kubernetes.yml
+ it-test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 17
+ distribution: 'zulu'
+ - name: Cache on push
+ if: github.event_name == 'push'
+ uses: actions/cache@v4
+ with:
+ path: ~/.gradle
+ key: ${{ runner.os }}-cd-it-${{ github.sha }}
+ # Restore build outputs from the previous commit (if successful), if current commit hasn't run successfully yet
+ restore-keys: |
+ ${{ runner.os }}-cd-it-${{ github.event.before }}
+ - name: Cache on pull_request
+ if: github.event_name == 'pull_request'
+ uses: actions/cache@v4
+ with:
+ path: ~/.gradle
+ key: ${{ runner.os }}-cd-it-${{ github.event.pull_request.head.sha }}
+ restore-keys: |
+ ${{ runner.os }}-cd-it-${{ github.event.before }}
+ # Separating integration tests by provider allows to have separate logs
+ - name: Amazon ECS Provider Integration Tests
+ run: ./gradlew --build-cache --no-daemon :clouddriver-ecs:integrationTest
+ - name: Artifacts Integration Tests
+ run: ./gradlew --build-cache :clouddriver-artifacts:integrationTest
+ - name: AWS EC2 Provider Integration Tests
+ run: ./gradlew --build-cache :clouddriver-aws:integrationTest
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 00000000000..7d97a23f395
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,69 @@
+name: PR Build
+
+on: [ pull_request ]
+
+env:
+ GRADLE_OPTS: -Dorg.gradle.daemon=false -Xmx12g -Xms12g
+ CONTAINER_REGISTRY: us-docker.pkg.dev/spinnaker-community/docker
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Create more disk space
+ run: sudo rm -rf /usr/share/dotnet && sudo rm -rf /opt/ghc && sudo rm -rf "/usr/local/share/boost" && sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 17
+ distribution: 'zulu'
+ cache: 'gradle'
+ - name: Prepare build variables
+ id: build_variables
+ run: |
+ echo REPO="${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT
+ echo VERSION="$(git describe --tags --abbrev=0 --match='v[0-9]*' | cut -c2-)-dev-pr-$(git rev-parse --short HEAD)-$(date --utc +'%Y%m%d%H%M')" >> $GITHUB_OUTPUT
+ - name: Build
+ env:
+ ORG_GRADLE_PROJECT_version: ${{ steps.build_variables.outputs.VERSION }}
+ run: ./gradlew build ${{ steps.build_variables.outputs.REPO }}-web:installDist
+ - name: Build slim container image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.slim
+ platforms: linux/amd64,linux/arm64
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:latest"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:latest-slim"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-slim"
+ - name: Build ubuntu container image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.ubuntu
+ platforms: linux/amd64,linux/arm64
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:latest-ubuntu"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-ubuntu"
+ - name: Build local slim container image for testing
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.slim
+ load: true
+ platforms: local
+ tags: |
+ "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}"
+ - name: Test local slim container image
+ env:
+ FULL_DOCKER_IMAGE_NAME: "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}"
+ run: ./gradlew ${{ steps.build_variables.outputs.REPO }}-integration:test
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000000..30c65c53c7d
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,158 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - "v[0-9]+.[0-9]+.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+"
+
+env:
+ GRADLE_OPTS: -Dorg.gradle.daemon=false -Xmx12g -Xms12g
+ CONTAINER_REGISTRY: us-docker.pkg.dev/spinnaker-community/docker
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ #https://github.com/NASA-IMPACT/hls-base/pull/17/files borrowed from this....
+ - name: Create more disk space
+ run: sudo rm -rf /usr/share/dotnet && sudo rm -rf /opt/ghc && sudo rm -rf "/usr/local/share/boost" && sudo rm -rf "$AGENT_TOOLSDIRECTORY"
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ # Given a tag, determine what branch we are on, so we can bump dependencies (or not)
+ - name: Get Branch
+ run: |
+ BRANCHES=$(git branch -r --contains ${{ github.ref }})
+ echo "BRANCHES is '${BRANCHES}'"
+ # Check for no branches explicitly...Otherwise echo adds a newline so wc thinks there's
+ # one branch. And echo -n makes it appears that there's one less branch than there
+ # actually is.
+ if [ -z "$BRANCHES" ]; then
+ echo "exactly one branch required to release clouddriver, but there are none"
+ exit 1
+ fi
+ NUM_BRANCHES=$(($(echo "$BRANCHES" | wc -l)))
+ echo "NUM_BRANCHES is '${NUM_BRANCHES}'"
+ if [ $NUM_BRANCHES -ne 1 ]; then
+ echo "exactly one branch required to release clouddriver, but there are $NUM_BRANCHES ($BRANCHES)"
+ exit 1
+ fi
+ BRANCH=$(echo $BRANCHES | xargs)
+ echo "exactly one branch ($BRANCH)"
+ echo BRANCH="$BRANCH" >> $GITHUB_ENV
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - uses: actions/setup-java@v4
+ with:
+ java-version: |
+ 17
+ distribution: 'zulu'
+ cache: 'gradle'
+ - name: Assemble release info
+ id: release_info
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ . .github/workflows/release_info.sh ${{ github.event.repository.full_name }}
+ echo CHANGELOG=$(echo -e "${CHANGELOG}") >> $GITHUB_OUTPUT
+ echo SKIP_RELEASE="${SKIP_RELEASE}" >> $GITHUB_OUTPUT
+ echo IS_CANDIDATE="${IS_CANDIDATE}" >> $GITHUB_OUTPUT
+ echo RELEASE_VERSION="${RELEASE_VERSION}" >> $GITHUB_OUTPUT
+ - name: Prepare build variables
+ id: build_variables
+ run: |
+ echo REPO="${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT
+ echo VERSION="$(git rev-parse --short HEAD)-$(date --utc +'%Y%m%d%H%M')" >> $GITHUB_OUTPUT
+ - name: Release build
+ env:
+ ORG_GRADLE_PROJECT_version: ${{ steps.release_info.outputs.RELEASE_VERSION }}
+ ORG_GRADLE_PROJECT_nexusPublishEnabled: true
+ ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }}
+ ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }}
+ ORG_GRADLE_PROJECT_nexusPgpSigningKey: ${{ secrets.NEXUS_PGP_SIGNING_KEY }}
+ ORG_GRADLE_PROJECT_nexusPgpSigningPassword: ${{ secrets.NEXUS_PGP_SIGNING_PASSWORD }}
+ run: |
+ ./gradlew --info build ${{ steps.build_variables.outputs.REPO }}-web:installDist publishToNexus closeAndReleaseNexusStagingRepository
+ - name: Publish apt packages to Google Artifact Registry
+ env:
+ ORG_GRADLE_PROJECT_version: ${{ steps.release_info.outputs.RELEASE_VERSION }}
+ ORG_GRADLE_PROJECT_artifactRegistryPublishEnabled: true
+ GAR_JSON_KEY: ${{ secrets.GAR_JSON_KEY }}
+ run: |
+ ./gradlew --info publish
+ - name: Login to Google Cloud
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: 'google-github-actions/auth@v2'
+ # use service account flow defined at: https://github.com/google-github-actions/upload-cloud-storage#authenticating-via-service-account-key-json
+ with:
+ credentials_json: '${{ secrets.GAR_JSON_KEY }}'
+ - name: Upload halconfig profiles to GCS
+ # https://console.cloud.google.com/storage/browser/halconfig
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: 'google-github-actions/upload-cloud-storage@v2'
+ with:
+ path: 'halconfig/'
+ destination: 'halconfig/${{ steps.build_variables.outputs.REPO }}/${{ steps.release_info.outputs.RELEASE_VERSION }}'
+ parent: false
+ - name: Login to GAR
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/login-action@v3
+ # use service account flow defined at: https://github.com/docker/login-action#service-account-based-authentication-1
+ with:
+ registry: us-docker.pkg.dev
+ username: _json_key
+ password: ${{ secrets.GAR_JSON_KEY }}
+ - name: Build and publish slim container image
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.slim
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.release_info.outputs.RELEASE_VERSION }}-unvalidated"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.release_info.outputs.RELEASE_VERSION }}-unvalidated-slim"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.release_info.outputs.RELEASE_VERSION }}-${{ steps.build_variables.outputs.VERSION }}-unvalidated-slim"
+ - name: Build and publish ubuntu container image
+ # Only run this on repositories in the 'spinnaker' org, not on forks.
+ if: startsWith(github.repository, 'spinnaker/')
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: Dockerfile.ubuntu
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: |
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.release_info.outputs.RELEASE_VERSION }}-unvalidated-ubuntu"
+ "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.release_info.outputs.RELEASE_VERSION }}-${{ steps.build_variables.outputs.VERSION }}-unvalidated-ubuntu"
+ - name: Create release
+ if: steps.release_info.outputs.SKIP_RELEASE == 'false'
+ uses: softprops/action-gh-release@v2
+ with:
+ body: |
+ ${{ steps.release_info.outputs.CHANGELOG }}
+ draft: false
+ name: ${{ github.event.repository.name }} ${{ github.ref_name }}
+ prerelease: ${{ steps.release_info.outputs.IS_CANDIDATE }}
+ tag_name: ${{ github.ref }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Pause before dependency bump
+ # The only dependency to bump is halyard, which only consumes from
+ # master since it has a different versioning scheme.
+ if: env.BRANCH == 'origin/master'
+ run: sleep 900
+ - name: Trigger dependency bump workflow
+ if: env.BRANCH == 'origin/master'
+ uses: peter-evans/repository-dispatch@v3
+ with:
+ token: ${{ secrets.SPINNAKER_GITHUB_TOKEN }}
+ event-type: bump-dependencies
+ client-payload: '{"ref": "${{ github.ref }}"}'
diff --git a/.github/workflows/release_info.sh b/.github/workflows/release_info.sh
new file mode 100755
index 00000000000..3c3a158aa59
--- /dev/null
+++ b/.github/workflows/release_info.sh
@@ -0,0 +1,41 @@
+#!/bin/bash -x
+
+NEW_TAG=${GITHUB_REF/refs\/tags\//}
+export NEW_TAG
+echo "NEW_TAG=$NEW_TAG"
+# Glob match previous tags which should be format v1.2.3. Avoids Deck's npm tagging.
+PREVIOUS_TAG=$(git describe --abbrev=0 --tags "${NEW_TAG}"^ --match 'v[0-9]*')
+export PREVIOUS_TAG
+echo "PREVIOUS_TAG=$PREVIOUS_TAG"
+CHANGELOG=$(git log "$NEW_TAG"..."$PREVIOUS_TAG" --oneline)
+export CHANGELOG
+echo "CHANGELOG=$CHANGELOG"
+
+# Format the changelog so it's markdown compatible
+CHANGELOG="${CHANGELOG//$'%'/%25}"
+CHANGELOG="${CHANGELOG//$'\n'/%0A}"
+CHANGELOG="${CHANGELOG//$'\r'/%0D}"
+
+# If the previous release tag is the same as this tag the user likely cut a release (and in the process created a tag), which means we can skip the need to create a release
+SKIP_RELEASE=$([[ "$PREVIOUS_TAG" = "$NEW_TAG" ]] && echo "true" || echo "false")
+export SKIP_RELEASE
+
+# https://github.com/fsaintjacques/semver-tool/blob/master/src/semver#L5-L14
+NAT='0|[1-9][0-9]*'
+ALPHANUM='[0-9]*[A-Za-z-][0-9A-Za-z-]*'
+IDENT="$NAT|$ALPHANUM"
+FIELD='[0-9A-Za-z-]+'
+SEMVER_REGEX="\
+^[vV]?\
+($NAT)\\.($NAT)\\.($NAT)\
+(\\-(${IDENT})(\\.(${IDENT}))*)?\
+(\\+${FIELD}(\\.${FIELD})*)?$"
+
+# Used in downstream steps to determine if the release should be marked as a "prerelease" and if the build should build candidate release artifacts
+IS_CANDIDATE=$([[ $NEW_TAG =~ $SEMVER_REGEX && -n ${BASH_REMATCH[4]} ]] && echo "true" || echo "false")
+export IS_CANDIDATE
+
+# This is the version string we will pass to the build, trim off leading 'v' if present
+RELEASE_VERSION=$([[ $NEW_TAG =~ $SEMVER_REGEX ]] && echo "${NEW_TAG:1}" || echo "${NEW_TAG}")
+export RELEASE_VERSION
+echo "RELEASE_VERSION=$RELEASE_VERSION"
diff --git a/.gitignore b/.gitignore
index 0d7617240f5..bf71aba9d5b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@ es-tmp/
clouddriver-oracle-bmcs/bmcs-sdk
gatling.conf
.DS_Store
+/plugins/
+*/test-tar/*
diff --git a/.idea/README.md b/.idea/README.md
new file mode 100644
index 00000000000..791237770d0
--- /dev/null
+++ b/.idea/README.md
@@ -0,0 +1,10 @@
+# Spinnaker IntelliJ IDEA files
+
+IntelliJ IDEA will modify some of these files from their checked-in versions when the project is
+opened. To work around this, the Spinnaker Gradle plugin will mark these files in Git as "assume
+unchanged", telling Git to ignore any local changes. If you want to commit changes to these files,
+you will need to undo that.
+
+```bash
+$ git update-index --no-assume-unchanged $FILENAME
+```
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 00000000000..a1757ae52c7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/ALS2.xml b/.idea/copyright/ALS2.xml
new file mode 100644
index 00000000000..2f6849bb338
--- /dev/null
+++ b/.idea/copyright/ALS2.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 00000000000..5c6994bea20
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml
new file mode 100644
index 00000000000..4a0e553c729
--- /dev/null
+++ b/.idea/google-java-format.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 00000000000..4aa6c33c739
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000000..35eb1ddfbbc
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.mergify.yml b/.mergify.yml
new file mode 100644
index 00000000000..501cf50af92
--- /dev/null
+++ b/.mergify.yml
@@ -0,0 +1,74 @@
+queue_rules:
+ - name: default
+ merge_method: squash
+ queue_conditions:
+ - check-success=build
+ - check-success=it-test
+
+pull_request_rules:
+ - name: Make sure PR are up to date before merging
+ description: This automatically updates PRs when they are out-of-date with the
+ base branch to avoid semantic conflicts (next step is using a merge queue).
+ conditions: []
+ actions:
+ update:
+ - name: Automatically merge backports to releases on succesful build
+ conditions:
+ - base~=^(release-)
+ - head~=^mergify\/bp\/
+ - "author=mergify[bot]"
+ actions:
+ queue:
+ name: default
+ label:
+ add: ["auto merged"]
+ - name: Automatically merge on CI success and review
+ conditions:
+ - base=master
+ - "label=ready to merge"
+ - "approved-reviews-by=@oss-approvers"
+ - "#approved-reviews-by>=1"
+ actions:
+ queue:
+ name: default
+ label:
+ add: ["auto merged"]
+ - name: Automatically merge release branch changes on CI success and release manager review
+ conditions:
+ - base~=^release-
+ - "label=ready to merge"
+ - "approved-reviews-by=@release-managers"
+ actions:
+ queue:
+ name: default
+ label:
+ add: ["auto merged"]
+ - name: Automatically merge PRs from maintainers on CI success and review
+ conditions:
+ - base=master
+ - "label=ready to merge"
+ - "author=@oss-approvers"
+ - "#approved-reviews-by>=1"
+ actions:
+ queue:
+ name: default
+ label:
+ add: ["auto merged"]
+ - name: Automatically merge autobump PRs on CI success
+ conditions:
+ - base~=^(master|release-)
+ - "label~=autobump-*"
+ - "author:spinnakerbot"
+ actions:
+ queue:
+ name: default
+ label:
+ add: ["auto merged"]
+ - name: Request reviews for autobump PRs on CI failure
+ conditions:
+ - base~=^(master|release-)
+ - "label~=autobump-*"
+ - base=master
+ actions:
+ request_reviews:
+ teams: ["oss-approvers"]
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b99bc1b055e..00000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: java
-jdk:
-- oraclejdk8
-sudo: required
-dist: trusty
-install: gradle/installViaTravis.sh
-script: gradle/buildViaTravis.sh
-before_cache: gradle/prepCaches.sh
-cache:
- directories:
- - $HOME/.gradle
-notifications:
- slack:
- secure: JtMdRjbeLkUjKe/IjiB7UEvEcOcKHT6lAVT31Hn5Kkw/U28JuscxOYTSD79b66Kxnq8kDFiWyhyUP5PfLp4+maX1zrYdieX0WhUkknsEvfP3Evcfcp6wYNexmxuTn3cmFLcSxKOQSr0KJ93YmBCHaGk/d2zt9NxhpXabtKptMfPrHFf9YvQMAtTLjU6U4pDvBOJGcW6KSD7ZwPYJXvyDCabm3EhCLG09IpJNj9P1XtpEBRA8FSWqLbAmmSx2yLsWfGvuf94niJ7C4xnAt2IRUTtYPwLv0H/ezptKLOhN1QOlkl784f7KHMimETyEFAnE94sjCJUQt32oB/nvowUjWtVajUKYYR0BmjtcD1jwS+nOwy+5sfBb8DN0JkEVijWoxXdlxY1jUZrGy0oF51UFxHvZYMxr20ScDqM+4SOq+TvRHpygRT3nRlcP8HugJErF1La8+sboDuTGy8Z6CI7or55/xrrXAhXolimc7s2TKNTpSqA9tGLehTBFcc/HDyG2MdvNxzCXNb4NHGKtLFvULI5I3nsr0eWpbmeWOGIeqG5dX9zr/YvyMfAXQf8qScQBQlwdS671lV2roJYZooZf5WI1wE/Bb3qApPXqSlW6EkyCUxRgJ4lCAgpbpU0B/ChyoKbFokRviinQFoVPQpkLiPGZMmrqRUnxh/NKN2OZymw=
-env:
- global:
- - secure: rItFfaK85MWIa0Dp9nsOwK5670d2JFA0bqfTCSuJNKfaFi4+45nQFUcVOccR2zY7oKCyylXxiDZKCz2P1j4gY+cYcxc0gC5VZzrGaP3Zde9EFdd3x9L4rxFxmjW09LNxFn1ilH8+KUE56W5Ak8o+9x9oYdEqP/B9N5omSf31mJtOveYCm6I8YHyEDI9/UznwzZMYNMTWYZyaOQZl8TVZVJS+oWBLgw4QlsllWc4J9RoPizFe51kCFgB2E8Ze0e05Kr76oZJ+64kBov36sUaOcSOls6eJ6VPN8lVRG9EQi75NnGlbmZvg8MT19v6uByuk14QvRbvr/B5lRC6GleH+kQ9ZrSFnLhYUMsq3tDrhdnsUtPZOYe93Tt/CsDhxuGpFsRYG8Itc8bDnyMbdhi0Eg5tTY/hlTG+e3/aUmIN5Ea/eqPmzGOcAzbLsC+zVx7FcC0C88EBQ/L/UDmH2htVs3L0MvBTquzm3suJ433eT8XoDV0YyfQ3mzf2PitJOVf+QNJxpLC1NwLmgca73HRgbsZ1pqkX/P6roOSZWdrMy+jwLupqxGwOuDR2yc7YILVEkFm2qfY67xs+r+ZMqVM2iB3mqwRIxLop8M0OvWnxS7VhfUD3ti5LGlGebMXLQXPJIsDNTHCTwephTFutvAlkr175VOyODAk32PsT5NWUkZXk=
- - secure: WGxAwuZM9idIQLUm69HfHZ1p+tQjTYVCXFNbIojrgcdO62z9UCIzpc+bPqYNI9KsxkWqtRK61JFRVh+OTN3Ua5g36dVIRG9Qs1N4RqkkIXpXlL6XU89J1BnLCHUEp3/JeD76I0rFVJSpVKea1clB45+VahgW8FkWKeNhJNHgDpQfifdVU0db/Hr4/423n5KHeOyek8MevO9EiQts8Fd4XQrYIcAfF+FIdQROzfEMEMDh8tvKCDzDkYqgtm2XjIPnBK2PzMbas5l8wzknMFmPaRnp3LC/etFyGsY2qdaEp5YrLVPtQMd4pZLA7x3xUXn7k1wRMAswvo2AuRny2CMSgf7xhU1Rf2HG5qUr2r38os9a2729WBslVkoeMW5tKDfQko425fUdhkeSpQbqVa1DPgMohdg9Of+c4jvQLE2rjSFev1RbKDAWRtw+/KSF3Ghz9O18k9glZYtNjmBNZzrrRGwXnoI+jldZAyEN7smpfeqdR3wa3jIwea3O7C+xmsI75vDI7R+0XGJkGs+2RjS/xISgXqD+MoiZnXVqsDlUCXNDEnWIGZMMg41FjYzmkWK2YzgZepuk4x5qQpUBZNe8QmHee5/pBHigtmC474nie4ciijtAQNiLoBKBlHnLUlbgPo1zODUKGa0K5ewoE8gASHZStVzAWtG4YFbqNVNdAEk=
-git:
- depth: 250
\ No newline at end of file
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 00000000000..80e4dcae7da
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,11 @@
+clouddriver-kubernetes/ @clanesf @german-muzquiz
+clouddriver-google/ @Nirmalyasen @plumpy @rebala @skandragon
+clouddriver-cloudfoundry/ @zachsmith1
+clouddriver-appengine/ @zachsmith1
+clouddriver-lambda/ @zachsmith1
+
+clouddriver-saga/ @cfieber
+clouddriver-core/ @cfieber
+
+clouddriver-aws/ @jeyrschabu @aravindmd @ajordens
+clouddriver-titus/ @jeyrschabu @aravindmd @ajordens
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index f8abbaad0ca..00000000000
--- a/Dockerfile
+++ /dev/null
@@ -1,32 +0,0 @@
-FROM openjdk:8
-
-MAINTAINER delivery-engineering@netflix.com
-
-COPY . workdir/
-
-WORKDIR workdir
-
-RUN GRADLE_USER_HOME=cache ./gradlew buildDeb -x test && \
- dpkg -i ./clouddriver-web/build/distributions/*.deb && \
- cd .. && \
- rm -rf workdir && \
- apt-get -y update && \
- apt-get -y install apt-transport-https && \
- echo "deb https://packages.cloud.google.com/apt cloud-sdk-trusty main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
- wget https://packages.cloud.google.com/apt/doc/apt-key.gpg && \
- apt-key add apt-key.gpg && \
- apt-get -y update && \
- apt-get -y install python2.7 unzip ca-certificates google-cloud-sdk && \
- apt-get clean
-
-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 && \
- chmod +x kubectl && \
- mv ./kubectl /usr/local/bin/kubectl
-
-RUN curl -o heptio-authenticator-aws https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/bin/linux/amd64/heptio-authenticator-aws && \
- chmod +x ./heptio-authenticator-aws && \
- mv ./heptio-authenticator-aws /usr/local/bin/heptio-authenticator-aws
-
-ENV PATH "$PATH:/usr/local/bin/heptio-authenticator-aws"
-
-CMD ["/opt/clouddriver/bin/clouddriver"]
diff --git a/Dockerfile.compile b/Dockerfile.compile
new file mode 100644
index 00000000000..3298b97566b
--- /dev/null
+++ b/Dockerfile.compile
@@ -0,0 +1,8 @@
+FROM ubuntu:jammy
+RUN apt-get update && apt-get install -y \
+ openjdk-17-jdk \
+ && rm -rf /var/lib/apt/lists/*
+LABEL maintainer="sig-platform@spinnaker.io"
+ENV GRADLE_USER_HOME /workspace/.gradle
+ENV GRADLE_OPTS "-Xmx12g -Xms12g"
+CMD ./gradlew --no-daemon clouddriver-web:installDist -x test
diff --git a/Dockerfile.slim b/Dockerfile.slim
index 3f779305819..17b9fcc862d 100644
--- a/Dockerfile.slim
+++ b/Dockerfile.slim
@@ -1,32 +1,62 @@
-FROM openjdk:8-jdk-alpine
-
-MAINTAINER delivery-engineering@netflix.com
-
-COPY ./clouddriver-web/build/install/clouddriver /opt/clouddriver
-
-RUN apk --no-cache add --update bash wget unzip 'python2>2.7.9' && \
- wget -nv https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.zip && \
- unzip -qq google-cloud-sdk.zip -d /opt && \
- rm google-cloud-sdk.zip && \
- CLOUDSDK_PYTHON="python2.7" /opt/google-cloud-sdk/install.sh --usage-reporting=false --bash-completion=false --additional-components app-engine-java && \
- rm -rf ~/.config/gcloud
-
-RUN wget https://storage.googleapis.com/kubernetes-release/release/stable.txt && wget https://storage.googleapis.com/kubernetes-release/release/$(cat stable.txt)/bin/linux/amd64/kubectl && \
- rm stable.txt && \
- chmod +x kubectl && \
- mv ./kubectl /usr/local/bin/kubectl
-
-RUN wget https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-06-05/bin/linux/amd64/heptio-authenticator-aws && \
- chmod +x ./heptio-authenticator-aws && \
- mv ./heptio-authenticator-aws /usr/local/bin/heptio-authenticator-aws
-
-ENV PATH "$PATH:/usr/local/bin/heptio-authenticator-aws"
-
-ENV PATH=$PATH:/opt/google-cloud-sdk/bin/
-
-RUN adduser -D -S spinnaker
+FROM python:3.12-alpine3.20
+LABEL maintainer="sig-platform@spinnaker.io"
+ARG TARGETARCH
+
+ENV KUBECTL_DEFAULT_RELEASE=1.22.17
+ENV KUBECTL_RELEASES="${KUBECTL_DEFAULT_RELEASE} 1.26.12 1.27.9 1.28.5 1.29.0"
+ENV AWS_CLI_VERSION=2.15.57
+ENV AWS_AIM_AUTHENTICATOR_VERSION=0.6.14
+ENV GOOGLE_CLOUD_SDK_VERSION=476.0.0
+ENV ECR_TOKEN_VERSION=v1.0.2
+
+ENV PATH="$PATH:/usr/local/bin/:/opt/google-cloud-sdk/bin/:/usr/local/bin/aws-iam-authenticator"
+
+RUN apk update \
+ && apk upgrade \
+ && apk --no-cache add --update \
+ bash \
+ ca-certificates \
+ curl \
+ wget \
+ openjdk17 \
+ git \
+ openssh-client \
+ unzip
+
+# AWS CLI 2
+RUN apk add aws-cli=${AWS_CLI_VERSION}-r0
+
+# Google cloud SDK
+RUN [ $TARGETARCH == 'amd64' ] && export GCP_ARCH="x86_64" || export GCP_ARCH="arm" \
+ && wget -nv https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && mkdir -p /opt && cd /opt \
+ && tar -xzf /google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && rm /google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && CLOUDSDK_PYTHON="python3" /opt/google-cloud-sdk/install.sh --usage-reporting=false --bash-completion=false \
+ --additional-components app-engine-java app-engine-go gke-gcloud-auth-plugin \
+ && rm -rf ~/.config/gcloud \
+ && rm -rf /opt/google-cloud-sdk/.install/.backup
+
+# kubectl + AWS IAM authenticator
+RUN for version in $KUBECTL_RELEASES; do \
+ release_version=$(echo ${version} | cut -d. -f1,2); \
+ wget -nv https://cdn.dl.k8s.io/release/v${version}/bin/linux/${TARGETARCH}/kubectl -O /usr/local/bin/kubectl-${release_version}; \
+ chmod +x /usr/local/bin/kubectl-${release_version}; \
+ done \
+ && ln -sf "/usr/local/bin/kubectl-$(echo ${KUBECTL_DEFAULT_RELEASE} | cut -d. -f1,2)" /usr/local/bin/kubectl \
+ && wget -nv -O aws-iam-authenticator https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v${AWS_AIM_AUTHENTICATOR_VERSION}/aws-iam-authenticator_${AWS_AIM_AUTHENTICATOR_VERSION}_linux_${TARGETARCH} \
+ && chmod +x ./aws-iam-authenticator \
+ && mv ./aws-iam-authenticator /usr/local/bin/aws-iam-authenticator\
+ && ln -sf /usr/local/bin/aws-iam-authenticator /usr/local/bin/heptio-authenticator-aws
+
+RUN rm /var/cache/apk/*
+
+RUN addgroup -S -g 10111 spinnaker
+RUN adduser -S -G spinnaker -u 10111 spinnaker
+
+COPY clouddriver-web/build/install/clouddriver /opt/clouddriver
+RUN mkdir -p /opt/clouddriver/plugins && chown -R spinnaker:nogroup /opt/clouddriver/plugins
USER spinnaker
-
-WORKDIR /home/spinnaker
+HEALTHCHECK CMD curl --fail http://localhost:7002/health
CMD ["/opt/clouddriver/bin/clouddriver"]
diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu
new file mode 100644
index 00000000000..27f33038b2a
--- /dev/null
+++ b/Dockerfile.ubuntu
@@ -0,0 +1,66 @@
+FROM ubuntu:jammy
+LABEL maintainer="sig-platform@spinnaker.io"
+ARG TARGETARCH
+ENV GOOGLE_CLOUD_SDK_VERSION=476.0.0
+ENV PATH="$PATH:/opt/google-cloud-sdk/bin/"
+ENV KUBECTL_DEFAULT_RELEASE=1.22.17
+ENV KUBECTL_RELEASES="${KUBECTL_DEFAULT_RELEASE} 1.26.12 1.27.9 1.28.5 1.29.0"
+ENV AWS_CLI_VERSION=2.15.57
+ENV AWS_AIM_AUTHENTICATOR_VERSION=0.6.14
+
+RUN apt-get update && apt-get install -y curl gnupg && \
+ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
+ echo "deb https://packages.cloud.google.com/apt cloud-sdk main" > /etc/apt/sources.list.d/cloud-sdk.list && \
+ apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install -y \
+ curl \
+ openjdk-17-jre-headless \
+ wget \
+ python3-pip \
+ python3 \
+ git \
+ openssh-client \
+ unzip && \
+ rm -rf ~/.config/gcloud
+
+# AWS CLI 2
+RUN if [ "${TARGETARCH}" = "arm64" ]; then \
+ wget -nv -O "awscliv2.zip" "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-${AWS_CLI_VERSION}.zip"; \
+ else \
+ wget -nv -O "awscliv2.zip" "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${AWS_CLI_VERSION}.zip"; \
+ fi && \
+ unzip awscliv2.zip && \
+ ./aws/install && \
+ rm -rf ./awscliv2.zip ./aws
+
+# kubectl + AWS IAM authenticator
+RUN for version in $KUBECTL_RELEASES; do \
+ release_version=$(echo ${version} | cut -d. -f1,2); \
+ wget -nv https://cdn.dl.k8s.io/release/v${version}/bin/linux/${TARGETARCH}/kubectl -O /usr/local/bin/kubectl-${release_version}; \
+ chmod +x /usr/local/bin/kubectl-${release_version}; \
+ done \
+ && ln -sf "/usr/local/bin/kubectl-$(echo ${KUBECTL_DEFAULT_RELEASE} | cut -d. -f1,2)" /usr/local/bin/kubectl \
+ && wget -nv -O aws-iam-authenticator https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v${AWS_AIM_AUTHENTICATOR_VERSION}/aws-iam-authenticator_${AWS_AIM_AUTHENTICATOR_VERSION}_linux_${TARGETARCH} \
+ && chmod +x ./aws-iam-authenticator \
+ && mv ./aws-iam-authenticator /usr/local/bin/aws-iam-authenticator\
+ && ln -sf /usr/local/bin/aws-iam-authenticator /usr/local/bin/heptio-authenticator-aws
+
+# Google cloud SDK
+RUN [ $TARGETARCH = 'amd64' ] && export GCP_ARCH="x86_64" || export GCP_ARCH="arm" \
+ && wget -nv https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && mkdir -p /opt && cd /opt \
+ && tar -xzf /google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && rm /google-cloud-sdk-${GOOGLE_CLOUD_SDK_VERSION}-linux-${GCP_ARCH}.tar.gz \
+ && CLOUDSDK_PYTHON="python3" /opt/google-cloud-sdk/install.sh --usage-reporting=false --bash-completion=false \
+ --additional-components app-engine-java app-engine-go gke-gcloud-auth-plugin \
+ && rm -rf ~/.config/gcloud \
+ && rm -rf /opt/google-cloud-sdk/.install/.backup
+
+
+RUN adduser --system --uid 10111 --group spinnaker
+COPY clouddriver-web/build/install/clouddriver /opt/clouddriver
+RUN mkdir -p /opt/clouddriver/plugins && chown -R spinnaker:nogroup /opt/clouddriver/plugins
+USER spinnaker
+HEALTHCHECK CMD curl --fail http://localhost:7002/health
+CMD ["/opt/clouddriver/bin/clouddriver"]
diff --git a/OWNERS.md b/OWNERS.md
new file mode 100644
index 00000000000..7ebe9a0557a
--- /dev/null
+++ b/OWNERS.md
@@ -0,0 +1,4 @@
+ajordens
+asher
+cfieber
+robzienert
diff --git a/README.md b/README.md
index be5d841bc2c..242d0732d0c 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
Spinnaker Cloud Provider Service
------------------------------------
-[![Build Status](https://api.travis-ci.org/spinnaker/clouddriver.svg?branch=master)](https://travis-ci.org/spinnaker/clouddriver)
+[![Build Status](https://github.com/spinnaker/clouddriver/workflows/Branch%20Build/badge.svg)](https://github.com/spinnaker/clouddriver/actions)
-This service is the main integration point for Spinnaker cloud providers like AWS, GCE, CloudFoundry, Azure etc.
+This service is the main integration point for Spinnaker cloud providers like AWS, GCE, CloudFoundry, Azure etc.
### Developing with Intellij
-To configure this repo as an Intellij project, run `./gradlew idea` in the root directory.
+To configure this repo as an Intellij project, run `./gradlew idea` in the root directory.
Some of the modules make use of [Lombok](https://projectlombok.org/), which will compile correctly on its own. However, for Intellij to make sense of the Lombok annotations, you'll need to install the [Lombok plugin](https://plugins.jetbrains.com/plugin/6317-lombok-plugin) as well as [check 'enable' under annotation processing](https://www.jetbrains.com/help/idea/configuring-annotation-processing.html#3).
diff --git a/build.gradle b/build.gradle
index d1215a81362..7d03bbf9ee9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,6 @@
/*
* Copyright 2014 Netflix, Inc.
+ * Copyright (c) 2018, salesforce.com, inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,107 +15,88 @@
* limitations under the License.
*/
-buildscript {
- ext {
- springBootVersion = "1.5.10.RELEASE"
- kotlinVersion = "1.2.41"
- junitPlatformVersion = "1.0.2"
- }
- repositories {
- mavenCentral()
- jcenter()
- maven { url "http://spinnaker.bintray.com/gradle" }
- maven { url "https://plugins.gradle.org/m2/" }
- }
- dependencies {
- classpath 'com.netflix.spinnaker.gradle:spinnaker-gradle-project:4.2.0'
- classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
- classpath "org.junit.platform:junit-platform-gradle-plugin:${junitPlatformVersion}"
- classpath "com.netflix.nebula:nebula-kotlin-plugin:${kotlinVersion}"
- }
+plugins {
+ id 'io.spinnaker.project' version "$spinnakerGradleVersion" apply false
+ id 'org.jetbrains.kotlin.jvm' version "$kotlinVersion"
+ id 'org.jetbrains.kotlin.plugin.allopen' version "$kotlinVersion" apply false
+ id "com.google.protobuf" version "0.8.12" apply false
}
allprojects {
- group = "com.netflix.spinnaker.clouddriver"
- apply plugin: 'spinnaker.project'
- apply plugin: 'groovy'
+ apply plugin: 'io.spinnaker.project'
+}
- ext {
- spinnakerDependenciesVersion = project.hasProperty('spinnakerDependenciesVersion') ? project.property('spinnakerDependenciesVersion') : '1.0.10'
- }
+subprojects {
+ group = "io.spinnaker.clouddriver"
- def checkLocalVersions = [spinnakerDependenciesVersion: spinnakerDependenciesVersion]
- if (ext.has('versions')) {
- def extVers = ext.get('versions')
- if (extVers instanceof Map) {
- checkLocalVersions.putAll(extVers)
- }
- }
+ if (name != "clouddriver-bom" && name != "clouddriver-api") {
+ apply plugin: 'java-library'
+ apply plugin: 'groovy'
+ apply plugin: 'kotlin'
+ apply plugin: "kotlin-allopen"
+ apply plugin: "jacoco"
- def localVersions = checkLocalVersions.findAll { it.value.endsWith('-SNAPSHOT') }
- if (localVersions) {
- logger.info("Enabling mavenLocal repo for $localVersions")
- repositories {
- mavenLocal()
- }
- }
+ sourceSets.main.java.srcDirs = []
+ sourceSets.main.groovy.srcDirs += ["src/main/java"]
- spinnaker {
- dependenciesVersion = spinnakerDependenciesVersion
- }
+ dependencies {
+ api enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
- test {
- testLogging {
- exceptionFormat = 'full'
- }
- if (project.hasProperty('slowTest')) {
- long slow = 250
- try {
- slow = Long.parseLong(project.property('slowTest'))
- } catch (Exception ex) {
- }
- afterTest { desc, result ->
- long duration = result.getEndTime() - result.getStartTime()
- if (duration > slow) {
- logger.warn("test exceeded $slow ms: $desc.className :: $desc.name ($duration milliseconds)")
- }
- }
+ compileOnly enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
+ compileOnly "org.projectlombok:lombok"
+
+ annotationProcessor enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
+ annotationProcessor "org.projectlombok:lombok"
+ annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
+
+ testAnnotationProcessor enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
+ testAnnotationProcessor "org.projectlombok:lombok"
+
+ testCompileOnly enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
+ testCompileOnly "org.projectlombok:lombok"
+
+ testRuntimeOnly enforcedPlatform("io.spinnaker.kork:kork-bom:$korkVersion")
+ testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine"
}
- minHeapSize = "512m"
- maxHeapSize = "512m"
- }
-}
-subprojects { project ->
-
- configurations {
- all {
- exclude group: 'javax.servlet', module: 'servlet-api'
- exclude group: 'javax.ws.rs', module: 'jsr311-api'
- resolutionStrategy {
- force 'org.antlr:antlr-runtime:3.5.2'
- eachDependency {
- if (it.requested.group == 'asm' || it.requested.group == 'org.ow2.asm') {
- it.useTarget group: 'org.ow2.asm', name: 'asm-all', version: '5.0.3'
- }
- if (it.requested.group == 'junit') {
- it.useTarget group: 'junit', name: 'junit', version: '4.12'
- }
- if (it.requested.group == 'cglib' || it.requested.name == 'cglib') {
- it.useTarget group: 'cglib', name: 'cglib', version: '3.2.0'
+ test {
+ useJUnitPlatform()
+ testLogging {
+ exceptionFormat = 'full'
+ if (project.hasProperty('slowTest')) {
+ long slow = 250
+ try {
+ slow = Long.parseLong(project.property('slowTest'))
+ } catch (Exception ex) {
}
- if (it.requested.group == 'com.google.guava') {
- it.useTarget group: 'com.google.guava', name: 'guava', version: '18.0'
- }
- if (it.requested.group == 'antlr') {
- it.useTarget group: 'org.antlr', name: it.requested.name, version: '3.5.2'
- }
- if (it.requested.group == 'org.apache.xbean') {
- it.useVersion '4.3'
+ afterTest { desc, result ->
+ long duration = result.getEndTime() - result.getStartTime()
+ if (duration > slow) {
+ logger.warn("test exceeded $slow ms: $desc.className :: $desc.name ($duration milliseconds)")
+ }
}
}
+
+ }
+ minHeapSize = "512m"
+ maxHeapSize = "1g"
+ maxParallelForks = 4
+ jacoco {
+ enabled = project.hasProperty('testCoverage')
}
}
+
+ // The test report requires tests to have run first
+ jacocoTestReport {
+ dependsOn test
+ }
+ }
+
+ if ([korkVersion, fiatVersion].any { it.endsWith("-SNAPSHOT") }) {
+ logger.info("Enabling mavenLocal")
+ repositories {
+ mavenLocal()
+ }
}
tasks.withType(JavaExec) {
@@ -122,11 +104,6 @@ subprojects { project ->
jvmArgs '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7102'
}
}
-
- dependencies {
- compile spinnaker.dependency('groovy')
- spinnaker.group('test')
- }
}
-defaultTasks ':clouddriver-web:bootRun'
+defaultTasks ':clouddriver-web:run'
diff --git a/cats/cats-core/cats-core.gradle b/cats/cats-core/cats-core.gradle
index afb2f5657c1..5d2e23405b7 100644
--- a/cats/cats-core/cats-core.gradle
+++ b/cats/cats-core/cats-core.gradle
@@ -1,6 +1,13 @@
dependencies {
- compile spinnaker.dependency('slf4jApi')
- compile spinnaker.dependency('jacksonAnnotations')
+ implementation project(":clouddriver-api")
- testCompile project(":cats:cats-test")
+ implementation "org.slf4j:slf4j-api"
+ implementation "com.fasterxml.jackson.core:jackson-annotations"
+ implementation "org.apache.groovy:groovy"
+ implementation "com.google.guava:guava"
+
+ testImplementation project(":cats:cats-test")
+
+ testImplementation "org.spockframework:spock-core"
+ testImplementation "org.junit.jupiter:junit-jupiter-api"
}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentController.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentController.java
index cff3049eba2..952ee714d9f 100644
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentController.java
+++ b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentController.java
@@ -20,22 +20,26 @@
import com.netflix.spinnaker.cats.provider.ProviderRegistry;
/**
- * AgentController schedules an AgentExecution for each Agent in each Provider in the ProviderRegistry.
- *
- * When the AgentControllers AgentExecution is invoked, it will trigger a load and cache cycle for that agent.
+ * AgentController schedules an AgentExecution for each Agent in each Provider in the
+ * ProviderRegistry.
+ *
+ *
When the AgentControllers AgentExecution is invoked, it will trigger a load and cache cycle
+ * for that agent.
*/
public class AgentController {
- public AgentController(ProviderRegistry providerRegistry,
- AgentScheduler agentScheduler,
- ExecutionInstrumentation executionInstrumentation) {
- for (Provider provider : providerRegistry.getProviders()) {
- if (provider instanceof AgentSchedulerAware) {
- ((AgentSchedulerAware)provider).setAgentScheduler(agentScheduler);
- }
+ public AgentController(
+ ProviderRegistry providerRegistry,
+ AgentScheduler agentScheduler,
+ ExecutionInstrumentation executionInstrumentation) {
+ for (Provider provider : providerRegistry.getProviders()) {
+ if (provider instanceof AgentSchedulerAware) {
+ ((AgentSchedulerAware) provider).setAgentScheduler(agentScheduler);
+ }
- for (Agent agent : provider.getAgents()) {
- agentScheduler.schedule(agent, agent.getAgentExecution(providerRegistry), executionInstrumentation);
- }
- }
+ for (Agent agent : provider.getAgents()) {
+ agentScheduler.schedule(
+ agent, agent.getAgentExecution(providerRegistry), executionInstrumentation);
+ }
}
+ }
}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentDataType.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentDataType.java
deleted file mode 100644
index 813826f850f..00000000000
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentDataType.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2014 Netflix, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.netflix.spinnaker.cats.agent;
-
-/**
- * Describes both the type name as well as authority for an Agent's provided data.
- *
- * If an agent is an Authoritative source of data, then it's resulting data set will be
- * considered the current complete set for that data source. If an agent is an Informative
- * source of data, its results will contribute to the data set for that type, but is never
- * considered the complete set of data, so will not result in deletions when elements are
- * no longer present.
- */
-public class AgentDataType {
- public static enum Authority {
- AUTHORITATIVE,
- INFORMATIVE;
-
- public AgentDataType forType(String typeName) {
- return new AgentDataType(typeName, this);
- }
- }
-
- private final String typeName;
- private final Authority authority;
-
- public AgentDataType(String typeName, Authority authority) {
- this.typeName = typeName;
- this.authority = authority;
- }
-
- public String getTypeName() {
- return typeName;
- }
-
- public Authority getAuthority() {
- return authority;
- }
-}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentIntervalAware.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentIntervalAware.java
index 4a41fd611dd..125dd99bcc5 100644
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentIntervalAware.java
+++ b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentIntervalAware.java
@@ -15,19 +15,16 @@
*/
/**
- * Identifies an entity (usually an Agent) that can report what interval it wants to be scheduled at.
+ * Identifies an entity (usually an Agent) that can report what interval it wants to be scheduled
+ * at.
*/
package com.netflix.spinnaker.cats.agent;
public interface AgentIntervalAware {
- /**
- * @return Agent's interval to be scheduled at in milliseconds.
- */
+ /** @return Agent's interval to be scheduled at in milliseconds. */
Long getAgentInterval();
- /**
- * @return Agent's error interval to be scheduled at in milliseconds.
- */
+ /** @return Agent's error interval to be scheduled at in milliseconds. */
default Long getAgentErrorInterval() {
return getAgentInterval();
}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentScheduler.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentScheduler.java
deleted file mode 100644
index 7d4ac7a0d8f..00000000000
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/AgentScheduler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2014 Netflix, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.netflix.spinnaker.cats.agent;
-
-/**
- * An AgentScheduler manages the execution of a CachingAgent.
- */
-public interface AgentScheduler {
- void schedule(Agent agent, AgentExecution agentExecution, ExecutionInstrumentation executionInstrumentation);
- default void unschedule(Agent agent) {};
-
- /**
- * @return True iff this scheduler supports synchronization between LoadData and OnDemand cache updates.
- */
- default boolean isAtomic() { return false; };
-
- /**
- * @param agent The agent being locked.
- *
- * @return A "Lock" that will allow exclusive access to updating this agent's cache data. null iff isAtomic == false.
- */
- default T tryLock(Agent agent) { return null; };
-
- /**
- * @param lock The lock being released.
- *
- * @return True iff the lock was still in our possession when the release call was made.
- */
- default boolean tryRelease(T lock) { return false; };
-
- /**
- * @param lock The lock being checked for validity.
- *
- * @return True iff the lock is still in our possession.
- */
- default boolean lockValid(T lock) { return false; };
-}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CacheResult.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CacheResult.java
deleted file mode 100644
index 3df1e21233f..00000000000
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CacheResult.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2014 Netflix, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.netflix.spinnaker.cats.agent;
-
-import com.netflix.spinnaker.cats.cache.CacheData;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * The result of a CachingAgent run.
- */
-public interface CacheResult {
- /**
- * @return The CacheDatas to cache, keyed by item type.
- */
- Map> getCacheResults();
-
- /**
- * Provides a means to explicitly evict items as a result of a CachingAgent execution.
- *
- * Note: Eviction will already occur based on the values in getCacheResults for all the types
- * that the CachingAgent authoritatively caches - this collection is for additional items
- * that were potentially cached out of band of a complete caching run.
- * @return The ids of items that should be explicitly evicted.
- */
- default Map> getEvictions() { return Collections.emptyMap(); }
-}
diff --git a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CachingAgent.java b/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CachingAgent.java
deleted file mode 100644
index 33119467321..00000000000
--- a/cats/cats-core/src/main/java/com/netflix/spinnaker/cats/agent/CachingAgent.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2014 Netflix, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.netflix.spinnaker.cats.agent;
-
-import com.netflix.spinnaker.cats.cache.CacheData;
-import com.netflix.spinnaker.cats.provider.ProviderCache;
-import com.netflix.spinnaker.cats.provider.ProviderRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * A CachingAgent loads one or more types of data.
- *
- * The data set for a caching agent is scoped to the provider and agent type. For example
- * an agent might load clusters for the AWS provider, and be scoped to a particular account
- * and region.
- */
-public interface CachingAgent extends Agent {
- /**
- * @return the data types this Agent returns
- * @see com.netflix.spinnaker.cats.agent.AgentDataType.Authority
- */
- Collection getProvidedDataTypes();
-
- /**
- * Triggered by an AgentScheduler to tell this Agent to load its data.
- *
- * @param providerCache Cache associated with this Agent's provider
- * @return the complete set of data for this Agent.
- */
- CacheResult loadData(ProviderCache providerCache);
-
- default Optional