From d757dbcdd6d2f5eb39cf2dd5e0e3e0be03d101a2 Mon Sep 17 00:00:00 2001 From: Rafael Gomes Date: Tue, 30 Apr 2024 16:10:07 -0300 Subject: [PATCH] Add specs with spec/dummy app (#132) --- .github/workflows/command_docs.yml | 2 +- .github/workflows/rspec-shared.yml | 56 ++ .github/workflows/rspec.yml | 50 +- .github/workflows/rubocop.yml | 12 +- .gitignore | 2 + .rspec | 1 - .simplecov_spawn.rb | 10 + CONTRIBUTING.md | 27 +- Gemfile.lock | 57 +- cpl.gemspec | 2 +- lib/command/apply_template.rb | 14 +- lib/command/base.rb | 16 +- lib/command/build_image.rb | 13 +- lib/command/cleanup_stale_apps.rb | 2 +- lib/command/copy_image_from_upstream.rb | 7 - lib/command/deploy_image.rb | 7 +- lib/command/exists.rb | 2 +- lib/command/generate.rb | 2 +- lib/command/info.rb | 10 +- lib/command/maintenance_off.rb | 2 +- lib/command/maintenance_on.rb | 2 +- lib/command/open.rb | 4 +- lib/command/open_console.rb | 4 +- lib/command/run.rb | 2 +- lib/command/run_cleanup.rb | 36 +- lib/command/run_detached.rb | 13 +- lib/constants/exit_code.rb | 7 + lib/core/config.rb | 2 +- lib/core/controlplane.rb | 83 ++- lib/core/controlplane_api_cli.rb | 6 +- lib/core/controlplane_api_direct.rb | 2 +- lib/core/shell.rb | 24 +- lib/cpl.rb | 17 +- .../Command_CleanupImages/deletes_images.yml | 323 ---------- .../displays_empty_message.yml | 83 --- .../lists_images_to_delete_based_on_days.yml | 83 --- ...images_to_delete_based_on_max_quantity.yml | 83 --- ..._delete_based_on_max_quantity_and_days.yml | 83 --- .../skips_delete_confirmation.yml | 323 ---------- .../displays_error_if_domain_is_not_found.yml | 43 -- ...ys_off_if_maintenance_mode_is_disabled.yml | 43 -- ...lays_on_if_maintenance_mode_is_enabled.yml | 43 -- .../disables_maintenance_mode.yml | 603 ------------------ .../displays_error_if_domain_is_not_found.yml | 43 -- ...r_if_maintenance_workload_is_not_found.yml | 83 --- ...f_maintenance_mode_is_already_disabled.yml | 43 -- .../displays_error_if_domain_is_not_found.yml | 43 -- ...r_if_maintenance_workload_is_not_found.yml | 83 --- ...if_maintenance_mode_is_already_enabled.yml | 43 -- .../enables_maintenance_mode.yml | 603 ------------------ ...r_if_maintenance_workload_is_not_found.yml | 43 -- ..._workload_does_not_use_shakacode_image.yml | 43 -- .../sets_page_for_maintenance_mode.yml | 123 ---- .../deletes_stale_run_workloads.yml | 243 ------- ...oads_for_all_apps_that_start_with_name.yml | 243 ------- .../displays_empty_message.yml | 83 --- .../lists_stale_run_workloads.yml | 83 --- ...oads_for_all_apps_that_start_with_name.yml | 83 --- .../skips_delete_confirmation.yml | 243 ------- ...tion_for_all_apps_that_start_with_name.yml | 243 ------- spec/command/apply_template_spec.rb | 173 +++++ spec/command/build_image_spec.rb | 80 +++ spec/command/cleanup_images_spec.rb | 285 +++++---- spec/command/cleanup_stale_apps_spec.rb | 139 ++++ spec/command/config_spec.rb | 30 + spec/command/copy_image_from_upstream_spec.rb | 179 ++++-- spec/command/delete_spec.rb | 90 +++ spec/command/deploy_image_spec.rb | 119 ++++ spec/command/env_spec.rb | 28 + spec/command/exists_spec.rb | 25 + spec/command/info_spec.rb | 259 ++++++++ spec/command/latest_image_spec.rb | 27 + spec/command/logs_spec.rb | 39 ++ spec/command/maintenance_off_spec.rb | 86 +-- spec/command/maintenance_on_spec.rb | 86 +-- spec/command/maintenance_set_page_spec.rb | 59 +- spec/command/maintenance_spec.rb | 53 +- spec/command/no_command_spec.rb | 23 + spec/command/open_console_spec.rb | 31 + spec/command/open_spec.rb | 44 ++ .../command/promote_app_from_upstream_spec.rb | 103 +++ spec/command/ps_restart_spec.rb | 40 ++ spec/command/ps_spec.rb | 67 ++ spec/command/ps_start_spec.rb | 37 ++ spec/command/ps_stop_spec.rb | 37 ++ spec/command/ps_wait_spec.rb | 28 + spec/command/run_cleanup_spec.rb | 259 ++++---- spec/command/run_detached_spec.rb | 94 +++ spec/command/run_spec.rb | 170 +++++ spec/command/setup_app_spec.rb | 81 +++ spec/command/version_spec.rb | 12 + spec/core/controlplane_api_direct_spec.rb | 8 +- spec/core/controlplane_spec.rb | 71 +++ spec/cpl_spec.rb | 2 + spec/dummy/{ => .controlplane}/Dockerfile | 13 +- spec/dummy/.controlplane/Dockerfile.invalid | 7 + spec/dummy/.controlplane/controlplane.yml | 204 ++++++ spec/dummy/.controlplane/entrypoint.sh | 32 + spec/dummy/.controlplane/release-invalid.sh | 3 + spec/dummy/.controlplane/release.sh | 3 + .../templates/detached-volume.yml | 6 + .../templates/fake-run-12345.yml | 26 + .../templates/fake-runner-12345.yml | 26 + .../templates/gvc-with-all-variables.yml | 30 + .../gvc-with-deprecated-variables.yml | 18 + .../templates/gvc-without-identity.yml | 11 + spec/dummy/.controlplane/templates/gvc.yml | 14 + .../dummy/.controlplane/templates/invalid.yml | 26 + .../maintenance-with-external-image.yml | 25 + .../.controlplane/templates/maintenance.yml | 25 + .../templates/postgres-with-volume.yml | 41 ++ .../.controlplane/templates/postgres.yml | 34 + .../templates/rails-with-non-app-image.yml | 26 + spec/dummy/.controlplane/templates/rails.yml | 26 + .../templates/secrets-policy.yml | 5 + spec/dummy/bin/docker-entrypoint | 8 - spec/dummy/config/database.yml | 74 +-- spec/spec_helper.rb | 43 +- spec/support/command_helpers.rb | 232 ++++++- spec/support/date_time_helpers.rb | 16 + spec/support/dummy_app_setup.rb | 22 + spec/support/spawned_command.rb | 38 ++ 122 files changed, 3608 insertions(+), 4867 deletions(-) create mode 100644 .github/workflows/rspec-shared.yml delete mode 100644 .rspec create mode 100644 .simplecov_spawn.rb create mode 100644 lib/constants/exit_code.rb delete mode 100644 spec/cassettes/Command_CleanupImages/deletes_images.yml delete mode 100644 spec/cassettes/Command_CleanupImages/displays_empty_message.yml delete mode 100644 spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_days.yml delete mode 100644 spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity.yml delete mode 100644 spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity_and_days.yml delete mode 100644 spec/cassettes/Command_CleanupImages/skips_delete_confirmation.yml delete mode 100644 spec/cassettes/Command_Maintenance/displays_error_if_domain_is_not_found.yml delete mode 100644 spec/cassettes/Command_Maintenance/displays_off_if_maintenance_mode_is_disabled.yml delete mode 100644 spec/cassettes/Command_Maintenance/displays_on_if_maintenance_mode_is_enabled.yml delete mode 100644 spec/cassettes/Command_MaintenanceOff/disables_maintenance_mode.yml delete mode 100644 spec/cassettes/Command_MaintenanceOff/displays_error_if_domain_is_not_found.yml delete mode 100644 spec/cassettes/Command_MaintenanceOff/displays_error_if_maintenance_workload_is_not_found.yml delete mode 100644 spec/cassettes/Command_MaintenanceOff/does_nothing_if_maintenance_mode_is_already_disabled.yml delete mode 100644 spec/cassettes/Command_MaintenanceOn/displays_error_if_domain_is_not_found.yml delete mode 100644 spec/cassettes/Command_MaintenanceOn/displays_error_if_maintenance_workload_is_not_found.yml delete mode 100644 spec/cassettes/Command_MaintenanceOn/does_nothing_if_maintenance_mode_is_already_enabled.yml delete mode 100644 spec/cassettes/Command_MaintenanceOn/enables_maintenance_mode.yml delete mode 100644 spec/cassettes/Command_MaintenanceSetPage/displays_error_if_maintenance_workload_is_not_found.yml delete mode 100644 spec/cassettes/Command_MaintenanceSetPage/does_nothing_if_maintenance_workload_does_not_use_shakacode_image.yml delete mode 100644 spec/cassettes/Command_MaintenanceSetPage/sets_page_for_maintenance_mode.yml delete mode 100644 spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads.yml delete mode 100644 spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads_for_all_apps_that_start_with_name.yml delete mode 100644 spec/cassettes/Command_RunCleanup/displays_empty_message.yml delete mode 100644 spec/cassettes/Command_RunCleanup/lists_stale_run_workloads.yml delete mode 100644 spec/cassettes/Command_RunCleanup/lists_stale_run_workloads_for_all_apps_that_start_with_name.yml delete mode 100644 spec/cassettes/Command_RunCleanup/skips_delete_confirmation.yml delete mode 100644 spec/cassettes/Command_RunCleanup/skips_delete_confirmation_for_all_apps_that_start_with_name.yml create mode 100644 spec/command/apply_template_spec.rb create mode 100644 spec/command/build_image_spec.rb create mode 100644 spec/command/cleanup_stale_apps_spec.rb create mode 100644 spec/command/config_spec.rb create mode 100644 spec/command/delete_spec.rb create mode 100644 spec/command/deploy_image_spec.rb create mode 100644 spec/command/env_spec.rb create mode 100644 spec/command/exists_spec.rb create mode 100644 spec/command/info_spec.rb create mode 100644 spec/command/latest_image_spec.rb create mode 100644 spec/command/logs_spec.rb create mode 100644 spec/command/no_command_spec.rb create mode 100644 spec/command/open_console_spec.rb create mode 100644 spec/command/open_spec.rb create mode 100644 spec/command/promote_app_from_upstream_spec.rb create mode 100644 spec/command/ps_restart_spec.rb create mode 100644 spec/command/ps_spec.rb create mode 100644 spec/command/ps_start_spec.rb create mode 100644 spec/command/ps_stop_spec.rb create mode 100644 spec/command/ps_wait_spec.rb create mode 100644 spec/command/run_detached_spec.rb create mode 100644 spec/command/run_spec.rb create mode 100644 spec/command/setup_app_spec.rb create mode 100644 spec/command/version_spec.rb create mode 100644 spec/core/controlplane_spec.rb rename spec/dummy/{ => .controlplane}/Dockerfile (92%) create mode 100644 spec/dummy/.controlplane/Dockerfile.invalid create mode 100644 spec/dummy/.controlplane/controlplane.yml create mode 100755 spec/dummy/.controlplane/entrypoint.sh create mode 100644 spec/dummy/.controlplane/release-invalid.sh create mode 100644 spec/dummy/.controlplane/release.sh create mode 100644 spec/dummy/.controlplane/templates/detached-volume.yml create mode 100644 spec/dummy/.controlplane/templates/fake-run-12345.yml create mode 100644 spec/dummy/.controlplane/templates/fake-runner-12345.yml create mode 100644 spec/dummy/.controlplane/templates/gvc-with-all-variables.yml create mode 100644 spec/dummy/.controlplane/templates/gvc-with-deprecated-variables.yml create mode 100644 spec/dummy/.controlplane/templates/gvc-without-identity.yml create mode 100644 spec/dummy/.controlplane/templates/gvc.yml create mode 100644 spec/dummy/.controlplane/templates/invalid.yml create mode 100644 spec/dummy/.controlplane/templates/maintenance-with-external-image.yml create mode 100644 spec/dummy/.controlplane/templates/maintenance.yml create mode 100644 spec/dummy/.controlplane/templates/postgres-with-volume.yml create mode 100644 spec/dummy/.controlplane/templates/postgres.yml create mode 100644 spec/dummy/.controlplane/templates/rails-with-non-app-image.yml create mode 100644 spec/dummy/.controlplane/templates/rails.yml create mode 100644 spec/dummy/.controlplane/templates/secrets-policy.yml delete mode 100755 spec/dummy/bin/docker-entrypoint create mode 100644 spec/support/date_time_helpers.rb create mode 100644 spec/support/dummy_app_setup.rb create mode 100644 spec/support/spawned_command.rb diff --git a/.github/workflows/command_docs.yml b/.github/workflows/command_docs.yml index 40cad101..26839ea4 100644 --- a/.github/workflows/command_docs.yml +++ b/.github/workflows/command_docs.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" + ruby-version: "2.7" bundler-cache: true - name: Install dependencies run: bundle install diff --git a/.github/workflows/rspec-shared.yml b/.github/workflows/rspec-shared.yml new file mode 100644 index 00000000..b9be9b80 --- /dev/null +++ b/.github/workflows/rspec-shared.yml @@ -0,0 +1,56 @@ +name: RSpec Shared + +on: + workflow_call: + inputs: + os-version: + required: true + type: string + ruby-version: + required: true + type: string + test-tag: + required: true + type: string + +jobs: + rspec: + runs-on: ${{ inputs.os-version }} + env: + RAILS_ENV: test + # We have to add "_CI" to the end, otherwise it messes with tests where we switch profiles, + # as Control Plane will try to use this token's profile instead. + CPLN_TOKEN_CI: ${{ secrets.CPLN_TOKEN }} + CPLN_ORG: ${{ vars.CPLN_ORG }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ inputs.ruby-version }} + bundler-cache: true + - name: Install dependencies + run: bundle install + - name: Install Control Plane tools + run: | + sudo npm install -g @controlplane/cli + cpln --version + - name: Setup Control Plane tools + run: | + cpln profile create default --token $CPLN_TOKEN_CI --org $CPLN_ORG + cpln image docker-login + - name: Run tests + run: bundle exec rspec --format documentation --tag ${{ inputs.test-tag }} + - name: Upload spec log + uses: actions/upload-artifact@master + if: always() + with: + name: spec-${{ inputs.test-tag }}-${{ github.run_id }}-${{ inputs.os-version }}-${{ inputs.ruby-version }}.log + path: spec.log + - name: Upload coverage results + uses: actions/upload-artifact@master + if: always() + with: + name: coverage-report-${{ inputs.test-tag }}-${{ github.run_id }}-${{ inputs.os-version }}-${{ inputs.ruby-version }} + path: coverage diff --git a/.github/workflows/rspec.yml b/.github/workflows/rspec.yml index cee61a69..a199e8a0 100644 --- a/.github/workflows/rspec.yml +++ b/.github/workflows/rspec.yml @@ -5,36 +5,24 @@ on: branches: - main pull_request: + workflow_dispatch: jobs: - rspec: - strategy: - matrix: - os: - - ubuntu-latest - - macos-latest - ruby: - - "2.7" - - "3.0" - runs-on: ${{ matrix.os }} - name: RSpec - env: - RAILS_ENV: test - steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} - bundler-cache: true - - name: Install dependencies - run: bundle install - - name: Run tests - run: bundle exec rspec - - name: Upload coverage results - uses: actions/upload-artifact@master - if: always() - with: - name: coverage-report-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.ruby }} - path: coverage + rspec-fast: + name: RSpec (Fast) + uses: ./.github/workflows/rspec-shared.yml + with: + os-version: ubuntu-latest + ruby-version: "2.7" + test-tag: ~slow + secrets: inherit + + rspec-slow: + name: RSpec (Slow) + uses: ./.github/workflows/rspec-shared.yml + if: github.event_name == 'workflow_dispatch' + with: + os-version: ubuntu-latest + ruby-version: "2.7" + test-tag: slow + secrets: inherit diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index fc627824..c7c08a26 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -8,15 +8,7 @@ on: jobs: rubocop: - strategy: - matrix: - os: - - ubuntu-latest - - macos-latest - ruby: - - "2.7" - - "3.0" - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest name: Rubocop steps: - name: Checkout code @@ -24,7 +16,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: ${{ matrix.ruby }} + ruby-version: "2.7" bundler-cache: true - name: Install dependencies run: bundle install diff --git a/.gitignore b/.gitignore index 781740d3..ac1cbfbf 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ # rspec failure tracking .rspec_status + +spec.log diff --git a/.rspec b/.rspec deleted file mode 100644 index c99d2e73..00000000 --- a/.rspec +++ /dev/null @@ -1 +0,0 @@ ---require spec_helper diff --git a/.simplecov_spawn.rb b/.simplecov_spawn.rb new file mode 100644 index 00000000..e83c82a5 --- /dev/null +++ b/.simplecov_spawn.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "simplecov" + +SimpleCov.start do + command_name "spawn" + enable_coverage :branch + + at_fork.call(Process.pid) +end diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70684070..619d44cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,13 +12,12 @@ git clone https://github.com/shakacode/heroku-to-control-plane alias cpl="~/projects/heroku-to-control-plane/bin/cpl" ``` -## Linting/Testing +## Linting Before committing or pushing code, be sure to: - Run `bundle exec rake update_command_docs` to sync any doc changes made in the source code to the docs - Run `bundle exec rubocop -a` to fix any linting errors -- Run `bundle exec rspec` to run the test suite You can also install [overcommit](https://github.com/sds/overcommit) and let it automatically check for you: @@ -28,6 +27,30 @@ gem install overcommit overcommit --install ``` +## Testing + +We use real apps for the tests. You'll need to have full access to a Control Plane org, and then set it as the env var `CPLN_ORG` when running the tests (or in the `.env` file): + +```sh +CPLN_ORG=your-org-for-tests bundle exec rspec +``` + +Tests are separated between fast and slow. Slow tests can take a long time and usually involve building / deploying images and waiting for workloads to be ready / not ready, so they should only be run once in a while. + +If you add a slow test, tag it with `slow`. Tests without a `slow` tag are considered fast by default. + +To run fast tests: + +```sh +CPLN_ORG=your-org-for-tests bundle exec rspec --tag ~slow +``` + +To run slow tests: + +```sh +CPLN_ORG=your-org-for-tests bundle exec rspec --tag slow +``` + ## Debugging 1. Use the `--verbose` option to see more detailed logs. diff --git a/Gemfile.lock b/Gemfile.lock index 0ac1fc5f..cf54947a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,60 +11,66 @@ PATH GEM remote: https://rubygems.org/ specs: - addressable (2.8.4) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) base64 (0.2.0) + bigdecimal (3.1.7) childprocess (4.1.0) - crack (0.4.5) + crack (1.0.0) + bigdecimal rexml debug (1.7.2) irb (>= 1.5.0) reline (>= 0.3.1) - diff-lcs (1.5.0) + diff-lcs (1.5.1) docile (1.4.0) dotenv (2.8.1) - hashdiff (1.0.1) + hashdiff (1.1.0) iniparse (1.5.0) io-console (0.7.2) irb (1.12.0) rdoc reline (>= 0.4.2) - json (2.6.3) + json (2.7.2) jwt (2.8.1) base64 overcommit (0.60.0) childprocess (>= 0.6.3, < 5) iniparse (~> 1.4) rexml (~> 3.2) - parallel (1.22.1) - parser (3.2.0.0) + parallel (1.24.0) + parser (3.3.0.5) ast (~> 2.4.1) + racc psych (5.1.2) stringio - public_suffix (5.0.1) + public_suffix (5.0.5) + racc (1.7.3) rainbow (3.1.1) - rake (13.0.6) - rdoc (6.6.2) + rake (13.2.1) + rdoc (6.6.3.1) psych (>= 4.0.0) - regexp_parser (2.6.2) - reline (0.4.3) + regexp_parser (2.9.0) + reline (0.5.1) io-console (~> 0.5) - rexml (3.2.5) + rexml (3.2.6) rspec (3.12.0) rspec-core (~> 3.12.0) rspec-expectations (~> 3.12.0) rspec-mocks (~> 3.12.0) - rspec-core (3.12.1) + rspec-core (3.12.3) rspec-support (~> 3.12.0) - rspec-expectations (3.12.2) + rspec-expectations (3.12.4) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-mocks (3.12.3) + rspec-mocks (3.12.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-support (3.12.0) - rubocop (1.45.0) + rspec-retry (0.6.2) + rspec-core (> 3.3) + rspec-support (3.12.2) + rubocop (1.45.1) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) @@ -74,16 +80,16 @@ GEM rubocop-ast (>= 1.24.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.24.1) - parser (>= 3.1.1.0) - rubocop-capybara (2.17.0) + rubocop-ast (1.31.2) + parser (>= 3.3.0.4) + rubocop-capybara (2.20.0) rubocop (~> 1.41) rubocop-rake (0.6.0) rubocop (~> 1.0) rubocop-rspec (2.18.1) rubocop (~> 1.33) rubocop-capybara (~> 2.17) - ruby-progressbar (1.11.0) + ruby-progressbar (1.13.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -92,9 +98,8 @@ GEM simplecov_json_formatter (0.1.4) stringio (3.1.0) thor (1.2.2) - timecop (0.9.6) - unicode-display_width (2.4.2) - vcr (6.1.0) + timecop (0.9.8) + unicode-display_width (2.5.0) webmock (3.18.1) addressable (>= 2.8.0) crack (>= 0.3.2) @@ -109,12 +114,12 @@ DEPENDENCIES overcommit (~> 0.60.0) rake (~> 13.0) rspec (~> 3.12.0) + rspec-retry (~> 0.6.2) rubocop (~> 1.45.0) rubocop-rake (~> 0.6.0) rubocop-rspec (~> 2.18.1) simplecov (~> 0.22.0) timecop (~> 0.9.6) - vcr (~> 6.1.0) webmock (~> 3.18.1) BUNDLED WITH diff --git a/cpl.gemspec b/cpl.gemspec index b39f723c..5655a70d 100644 --- a/cpl.gemspec +++ b/cpl.gemspec @@ -23,12 +23,12 @@ Gem::Specification.new do |spec| spec.add_development_dependency "overcommit", "~> 0.60.0" spec.add_development_dependency "rspec", "~> 3.12.0" + spec.add_development_dependency "rspec-retry", "~> 0.6.2" spec.add_development_dependency "rubocop", "~> 1.45.0" spec.add_development_dependency "rubocop-rake", "~> 0.6.0" spec.add_development_dependency "rubocop-rspec", "~> 2.18.1" spec.add_development_dependency "simplecov", "~> 0.22.0" spec.add_development_dependency "timecop", "~> 0.9.6" - spec.add_development_dependency "vcr", "~> 6.1.0" spec.add_development_dependency "webmock", "~> 3.18.1" spec.files = `git ls-files -z`.split("\x0").reject do |file| diff --git a/lib/command/apply_template.rb b/lib/command/apply_template.rb index a1d00410..a937fbd9 100644 --- a/lib/command/apply_template.rb +++ b/lib/command/apply_template.rb @@ -64,15 +64,15 @@ def call # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, M pending_templates.each do |template, filename| step("Applying template '#{template}'", abort_on_error: false) do items = apply_template(filename) - if items - items.each do |item| - report_success(item) - end - else + unless items report_failure(template) + next false end - $CHILD_STATUS.success? + items.each do |item| + report_success(item) + end + true end end @@ -82,7 +82,7 @@ def call # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, M print_failed_templates print_skipped_templates - exit(1) if @failed_templates.any? + exit(ExitCode::ERROR_DEFAULT) if @failed_templates.any? end private diff --git a/lib/command/base.rb b/lib/command/base.rb index 12c75389..0ed75545 100644 --- a/lib/command/base.rb +++ b/lib/command/base.rb @@ -312,8 +312,9 @@ def latest_image_from(items, app_name: config.app, name_only: true) end end - def latest_image(app = config.app, org = config.org) + def latest_image(app = config.app, org = config.org, refresh: false) @latest_image ||= {} + @latest_image[app] = nil if refresh @latest_image[app] ||= begin items = cp.query_images(app, org)["items"] @@ -377,7 +378,7 @@ def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disab if retry_on_failure until (success = yield) progress.print(".") - sleep 1 + Kernel.sleep(1) end else success = yield @@ -394,10 +395,6 @@ def cp @cp ||= Controlplane.new(config) end - def perform!(cmd) - system(cmd) || exit(1) - end - def app_location_link "/org/#{config.org}/location/#{config.location}" end @@ -422,6 +419,13 @@ def app_secrets_policy "#{app_secrets}-policy" end + def ensure_docker_running! + result = Shell.cmd("docker", "version", capture_stderr: true) + return if result[:success] + + raise "Can't run Docker. Please make sure that it's installed and started, then try again." + end + private # returns 0 if no prior image diff --git a/lib/command/build_image.rb b/lib/command/build_image.rb index d76435eb..7694bd83 100644 --- a/lib/command/build_image.rb +++ b/lib/command/build_image.rb @@ -38,16 +38,11 @@ def call # rubocop:disable Metrics/MethodLength docker_args: config.args, build_args: build_args) - progress.puts("\nPushed image to '/org/#{config.org}/image/#{image_name}'.") - end - - private - - def ensure_docker_running! - `docker version > /dev/null 2>&1` - return if $CHILD_STATUS.success? + progress.puts("\nPushed image to '/org/#{config.org}/image/#{image_name}'.\n\n") - raise "Can't run Docker. Please make sure that it's installed and started, then try again." + step("Waiting for image to be available", retry_on_failure: true) do + image_name == latest_image(refresh: true) + end end end end diff --git a/lib/command/cleanup_stale_apps.rb b/lib/command/cleanup_stale_apps.rb index fb813caf..2d02820e 100644 --- a/lib/command/cleanup_stale_apps.rb +++ b/lib/command/cleanup_stale_apps.rb @@ -21,7 +21,7 @@ def call # rubocop:disable Metrics/MethodLength progress.puts("Stale apps:") stale_apps.each do |app| - progress.puts(" #{app[:name]} (#{Shell.color((app[:date]).to_s, :red)})") + progress.puts(" - #{app[:name]} (#{Shell.color((app[:date]).to_s, :red)})") end return unless confirm_delete diff --git a/lib/command/copy_image_from_upstream.rb b/lib/command/copy_image_from_upstream.rb index 1bd8e313..4ee22d77 100644 --- a/lib/command/copy_image_from_upstream.rb +++ b/lib/command/copy_image_from_upstream.rb @@ -44,13 +44,6 @@ def call # rubocop:disable Metrics/MethodLength private - def ensure_docker_running! - `docker version > /dev/null 2>&1` - return if $CHILD_STATUS.success? - - raise "Can't run Docker. Please make sure that it's installed and started, then try again." - end - def ensure_upstream_org! return if @upstream_org diff --git a/lib/command/deploy_image.rb b/lib/command/deploy_image.rb index 63707c0c..574725b4 100644 --- a/lib/command/deploy_image.rb +++ b/lib/command/deploy_image.rb @@ -54,7 +54,12 @@ def run_release_script raise "Can't find release script in '#{release_script_path}'." unless File.exist?(release_script_path) progress.puts("Running release script...\n\n") - perform!("bash #{release_script_path}") + + result = Shell.cmd("bash", release_script_path, capture_stderr: true) + progress.puts(result[:output]) + + raise "Failed to run release script." unless result[:success] + progress.puts end end diff --git a/lib/command/exists.rb b/lib/command/exists.rb index cd847eb6..080d620b 100644 --- a/lib/command/exists.rb +++ b/lib/command/exists.rb @@ -17,7 +17,7 @@ class Exists < Base EX def call - exit(!cp.fetch_gvc.nil?) + exit(cp.fetch_gvc.nil? ? ExitCode::ERROR_DEFAULT : ExitCode::SUCCESS) end end end diff --git a/lib/command/generate.rb b/lib/command/generate.rb index 711f8e19..288eba65 100644 --- a/lib/command/generate.rb +++ b/lib/command/generate.rb @@ -5,7 +5,7 @@ class Generator < Thor::Group include Thor::Actions def copy_files - directory("generator_templates", ".controlplane") + directory("generator_templates", ".controlplane", verbose: ENV.fetch("HIDE_COMMAND_OUTPUT", nil) != "true") end def self.source_root diff --git a/lib/command/info.rb b/lib/command/info.rb index 1dbbdaf5..0a6b8176 100644 --- a/lib/command/info.rb +++ b/lib/command/info.rb @@ -76,7 +76,7 @@ def orgs result.push(config.org) else config.apps.each do |_, app_options| - org = app_options[:cpln_org] + org = app_org(app_options) result.push(org) if org && !result.include?(org) end end @@ -90,14 +90,18 @@ def apps(org) config.apps.each do |app_name, app_options| next if config.app && !config.app_matches?(config.app, app_name, app_options) - app_org = app_options[:cpln_org] - result.push(app_name.to_s) if app_org == org + current_app_org = app_org(app_options) + result.push(app_name.to_s) if current_app_org == org end result += @app_workloads.keys.map(&:to_s) result.uniq.sort end + def app_org(app_options) + app_options[:cpln_org] + end + def any_app_starts_with?(app) @app_workloads.keys.find { |app_name| config.app_matches?(app_name, app, config.apps[app.to_sym]) } end diff --git a/lib/command/maintenance_off.rb b/lib/command/maintenance_off.rb index 4512a861..8636f2c1 100644 --- a/lib/command/maintenance_off.rb +++ b/lib/command/maintenance_off.rb @@ -48,7 +48,7 @@ def call # rubocop:disable Metrics/MethodLength cp.set_domain_workload(domain_data, one_off_workload) # Give it a bit of time for the domain to update - sleep 30 + Kernel.sleep(30) end progress.puts diff --git a/lib/command/maintenance_on.rb b/lib/command/maintenance_on.rb index 14b8bf91..bf86a9fd 100644 --- a/lib/command/maintenance_on.rb +++ b/lib/command/maintenance_on.rb @@ -48,7 +48,7 @@ def call # rubocop:disable Metrics/MethodLength cp.set_domain_workload(domain_data, maintenance_workload) # Give it a bit of time for the domain to update - sleep 30 + Kernel.sleep(30) end progress.puts diff --git a/lib/command/open.rb b/lib/command/open.rb index 199597e0..8d7300e7 100644 --- a/lib/command/open.rb +++ b/lib/command/open.rb @@ -25,9 +25,9 @@ def call workload = config.options[:workload] || config[:one_off_workload] data = cp.fetch_workload!(workload) url = data["status"]["endpoint"] - opener = `which xdg-open open`.split("\n").grep_v("not found").first + opener = Shell.cmd("which", "xdg-open", "open")[:output].split("\n").grep_v("not found").first - exec %(#{opener} "#{url}") + Kernel.exec(opener, url) end end end diff --git a/lib/command/open_console.rb b/lib/command/open_console.rb index d9280025..053054ef 100644 --- a/lib/command/open_console.rb +++ b/lib/command/open_console.rb @@ -18,9 +18,9 @@ def call url = "https://console.cpln.io/console/org/#{config.org}/gvc/#{config.app}" url += "/workload/#{workload}" if workload url += "/-info" - opener = `which xdg-open open`.split("\n").grep_v("not found").first + opener = Shell.cmd("which", "xdg-open", "open")[:output].split("\n").grep_v("not found").first - exec %(#{opener} "#{url}") + Kernel.exec(opener, url) end end end diff --git a/lib/command/run.rb b/lib/command/run.rb index 35a4ae6f..d8a9aa7a 100644 --- a/lib/command/run.rb +++ b/lib/command/run.rb @@ -127,7 +127,7 @@ def runner_script # rubocop:disable Metrics/MethodLength if config.options[:terminal_size] rows, cols = config.options[:terminal_size].split(",") else - rows, cols = `stty size`.split(/\s+/) + rows, cols = Shell.cmd("stty", "size")[:output].split(/\s+/) end script += "stty rows #{rows}\nstty cols #{cols}\n" if rows && cols end diff --git a/lib/command/run_cleanup.rb b/lib/command/run_cleanup.rb index 2f99c508..74f1543b 100644 --- a/lib/command/run_cleanup.rb +++ b/lib/command/run_cleanup.rb @@ -21,12 +21,7 @@ def call # rubocop:disable Metrics/MethodLength progress.puts("Stale run workloads:") stale_run_workloads.each do |workload| - output = "" - output += if config.should_app_start_with?(config.app) - " #{workload[:app]} - #{workload[:name]}" - else - " #{workload[:name]}" - end + output = " - #{workload[:app]}: #{workload[:name]}" output += " (#{Shell.color("#{workload[:date]} - #{workload[:days]} days ago", :red)})" progress.puts(output) end @@ -41,28 +36,12 @@ def call # rubocop:disable Metrics/MethodLength private - def app_matches?(app, app_name, app_options) - app == app_name.to_s || (app_options[:match_if_app_name_starts_with] && app.start_with?(app_name.to_s)) - end - - def find_app_options(app) - @app_options ||= {} - @app_options[app] ||= config.apps.find do |app_name, app_options| - app_matches?(app, app_name, app_options) - end&.last - end - - def find_workloads(app) - app_options = find_app_options(app) - return [] if app_options.nil? - - (app_options[:app_workloads] + app_options[:additional_workloads] + [app_options[:one_off_workload]]).uniq - end - def stale_run_workloads # rubocop:disable Metrics/MethodLength @stale_run_workloads ||= begin - defined_workloads = find_workloads(config.app) + defined_workloads = (config.current[:app_workloads] + + config.current[:additional_workloads] + + [config.current[:one_off_workload]]).uniq run_workloads = [] @@ -103,12 +82,7 @@ def confirm_delete end def delete_workload(workload) - message = if config.should_app_start_with?(config.app) - "Deleting run workload '#{workload[:app]} - #{workload[:name]}'" - else - "Deleting run workload '#{workload[:name]}'" - end - step(message) do + step("Deleting run workload '#{workload[:app]}: #{workload[:name]}'") do cp.delete_workload(workload[:name], workload[:app]) end end diff --git a/lib/command/run_detached.rb b/lib/command/run_detached.rb index 35e85706..8cfe8dd0 100644 --- a/lib/command/run_detached.rb +++ b/lib/command/run_detached.rb @@ -45,6 +45,7 @@ class RunDetached < Base # rubocop:disable Metrics/ClassLength EX WORKLOAD_SLEEP_CHECK = 2 + MAX_RETRIES = Float::INFINITY attr_reader :location, :workload_to_clone, :workload_clone, :container @@ -60,7 +61,7 @@ def call wait_for_workload(workload_clone) show_logs_waiting ensure - exit(1) if @crashed + exit(ExitCode::ERROR_DEFAULT) if @crashed end private @@ -138,14 +139,18 @@ def runner_script # rubocop:disable Metrics/MethodLength def show_logs_waiting # rubocop:disable Metrics/MethodLength progress.puts("Scheduled, fetching logs (it's a cron job, so it may take up to a minute to start)...\n\n") + retries = 0 begin @finished = false while cp.fetch_workload(workload_clone) && !@finished - sleep(WORKLOAD_SLEEP_CHECK) + Kernel.sleep(WORKLOAD_SLEEP_CHECK) print_uniq_logs end rescue RuntimeError => e - progress.puts(Shell.color("ERROR: #{e}", :red)) + raise "#{e} Exiting..." unless retries < MAX_RETRIES + + progress.puts(Shell.color("ERROR: #{e} Retrying...", :red)) + retries += 1 retry end progress.puts("\nFinished workload and logger.") @@ -159,7 +164,7 @@ def print_uniq_logs (entries - @printed_log_entries).sort.each do |(_ts, val)| @crashed = true if val.match?(/^----- CRASHED -----$/) @finished = true if val.match?(/^-- FINISHED RUNNER SCRIPT(, DELETING WORKLOAD)? --$/) - puts val + progress.puts(val) end @printed_log_entries = entries # as well truncate old entries if any diff --git a/lib/constants/exit_code.rb b/lib/constants/exit_code.rb new file mode 100644 index 00000000..4bda8de4 --- /dev/null +++ b/lib/constants/exit_code.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ExitCode + SUCCESS = 0 + ERROR_DEFAULT = 64 + INTERRUPT = 130 +end diff --git a/lib/core/config.rb b/lib/core/config.rb index a74f5f98..d58972ed 100644 --- a/lib/core/config.rb +++ b/lib/core/config.rb @@ -174,7 +174,7 @@ def ensure_required_options! # rubocop:disable Metrics/CyclomaticComplexity end def config_file_path # rubocop:disable Metrics/MethodLength - @config_file_path ||= begin + @config_file_path ||= ENV["CONFIG_FILE_PATH"] || begin path = Pathname.new(".").expand_path loop do diff --git a/lib/core/controlplane.rb b/lib/core/controlplane.rb index 3a84d95e..a34608e8 100644 --- a/lib/core/controlplane.rb +++ b/lib/core/controlplane.rb @@ -25,13 +25,11 @@ def profile_exists?(profile) def profile_create(profile, token) sensitive_data_pattern = /(?<=--token )(\S+)/ cmd = "cpln profile create #{profile} --token #{token}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd, sensitive_data_pattern: sensitive_data_pattern) end def profile_delete(profile) cmd = "cpln profile delete #{profile}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end @@ -68,25 +66,21 @@ def image_delete(image) def image_login(org_name = config.org) cmd = "cpln image docker-login --org #{org_name}" - cmd += " > /dev/null 2>&1" if Shell.should_hide_output? - perform!(cmd) + perform!(cmd, output_mode: :none) end def image_pull(image) cmd = "docker pull #{image}" - cmd += " > /dev/null" if Shell.should_hide_output? - perform!(cmd) + perform!(cmd, output_mode: :none) end def image_tag(old_tag, new_tag) cmd = "docker tag #{old_tag} #{new_tag}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end def image_push(image) cmd = "docker push #{image}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end @@ -156,12 +150,11 @@ def workload_get_replicas(workload, location:) def workload_get_replicas_safely(workload, location:) cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml" - cmd += " 2> /dev/null" if Shell.should_hide_output? Shell.debug("CMD", cmd) - result = `#{cmd}` - $CHILD_STATUS.success? ? YAML.safe_load(result) : nil + result = Shell.cmd(cmd, capture_stderr: true) + YAML.safe_load(result[:output]) if result[:success] end def fetch_workload_deployments(workload) @@ -191,7 +184,6 @@ def workload_deployments_ready?(workload, expected_status:) def workload_set_image_ref(workload, container:, image:) cmd = "cpln workload update #{workload} #{gvc_org}" cmd += " --set spec.containers.#{container}.image=/org/#{config.org}/image/#{image}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end @@ -219,7 +211,6 @@ def set_workload_suspend(workload, value) def workload_force_redeployment(workload) cmd = "cpln workload force-redeployment #{workload} #{gvc_org}" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end @@ -231,14 +222,14 @@ def workload_connect(workload, location:, container: nil, shell: nil) cmd = "cpln workload connect #{workload} #{gvc_org} --location #{location}" cmd += " --container #{container}" if container cmd += " --shell #{shell}" if shell - perform!(cmd) + perform!(cmd, output_mode: :all) end def workload_exec(workload, location:, container: nil, command: nil) cmd = "cpln workload exec #{workload} #{gvc_org} --location #{location}" cmd += " --container #{container}" if container cmd += " -- #{command}" - perform!(cmd) + perform!(cmd, output_mode: :all) end # volumeset @@ -297,7 +288,7 @@ def set_domain_workload(data, workload) def logs(workload:) cmd = "cpln logs '{workload=\"#{workload}\"}' --org #{org} -t -o raw --limit 200" - perform!(cmd) + perform!(cmd, output_mode: :all) end def log_get(workload:, from:, to:) @@ -318,7 +309,6 @@ def fetch_policy(policy) def bind_identity_to_policy(identity_link, policy) cmd = "cpln policy add-binding #{policy} --org #{org} --identity #{identity_link} --permission reveal" - cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end @@ -333,13 +323,17 @@ def apply_template(data) # rubocop:disable Metrics/MethodLength Shell.debug("CMD", cmd) - result = `#{cmd}` - $CHILD_STATUS.success? ? parse_apply_result(result) : false + result = Shell.cmd(cmd) + parse_apply_result(result[:output]) if result[:success] else Shell.debug("CMD", cmd) - result = `#{cmd}` - $CHILD_STATUS.success? ? parse_apply_result(result) : exit(1) + result = Shell.cmd(cmd) + if result[:success] + parse_apply_result(result[:output]) + else + Shell.abort("Command exited with non-zero status.") + end end end end @@ -383,23 +377,56 @@ def parse_apply_result(result) # rubocop:disable Metrics/CyclomaticComplexity, M private - def perform(cmd) - Shell.debug("CMD", cmd) + # `output_mode` can be :all, :errors_only or :none. + # If not provided, it will be determined based on the `HIDE_COMMAND_OUTPUT` env var + # or the return value of `Shell.should_hide_output?`. + def build_command(cmd, output_mode: nil) # rubocop:disable Metrics/MethodLength + output_mode ||= determine_command_output_mode + + case output_mode + when :all + cmd + when :errors_only + "#{cmd} > /dev/null" + when :none + "#{cmd} > /dev/null 2>&1" + else + raise "Invalid command output mode '#{output_mode}'." + end + end - system(cmd) + def determine_command_output_mode + if ENV.fetch("HIDE_COMMAND_OUTPUT", nil) == "true" + :none + elsif Shell.should_hide_output? + :errors_only + else + :all + end end - def perform!(cmd, sensitive_data_pattern: nil) + def perform(cmd, output_mode: nil, sensitive_data_pattern: nil) + cmd = build_command(cmd, output_mode: output_mode) + Shell.debug("CMD", cmd, sensitive_data_pattern: sensitive_data_pattern) - system(cmd) || exit(1) + Kernel.system(cmd) + end + + def perform!(cmd, output_mode: nil, sensitive_data_pattern: nil) + success = perform(cmd, output_mode: output_mode, sensitive_data_pattern: sensitive_data_pattern) + success || Shell.abort("Command exited with non-zero status.") end def perform_yaml(cmd) Shell.debug("CMD", cmd) - result = `#{cmd}` - $CHILD_STATUS.success? ? YAML.safe_load(result) : exit(1) + result = Shell.cmd(cmd) + if result[:success] + YAML.safe_load(result[:output]) + else + Shell.abort("Command exited with non-zero status.") + end end def gvc_org diff --git a/lib/core/controlplane_api_cli.rb b/lib/core/controlplane_api_cli.rb index c90c97da..57f00326 100644 --- a/lib/core/controlplane_api_cli.rb +++ b/lib/core/controlplane_api_cli.rb @@ -2,9 +2,9 @@ class ControlplaneApiCli def call(url, method:) - response = `cpln rest #{method} #{url} -o json` - raise(response) unless $CHILD_STATUS.success? + result = Shell.cmd("cpln", "rest", method, url, "-o", "json", capture_stderr: true) + raise(result[:output]) unless result[:success] - JSON.parse(response) + JSON.parse(result[:output]) end end diff --git a/lib/core/controlplane_api_direct.rb b/lib/core/controlplane_api_direct.rb index bc4ef9c2..b5ba5ce9 100644 --- a/lib/core/controlplane_api_direct.rb +++ b/lib/core/controlplane_api_direct.rb @@ -75,7 +75,7 @@ def api_token # rubocop:disable Metrics/MethodLength } if @@api_token[:token].nil? @@api_token = { - token: `cpln profile token`.chomp, + token: Shell.cmd("cpln", "profile", "token")[:output].chomp, comes_from_profile: true } end diff --git a/lib/core/shell.rb b/lib/core/shell.rb index c9768eeb..654b42cb 100644 --- a/lib/core/shell.rb +++ b/lib/core/shell.rb @@ -9,10 +9,6 @@ def self.shell @shell ||= Thor::Shell::Color.new end - def self.stderr - @stderr ||= $stderr - end - def self.use_tmp_stderr @tmp_stderr = Tempfile.create @@ -40,15 +36,16 @@ def self.confirm(message) end def self.warn(message) - stderr.puts(color("WARNING: #{message}", :yellow)) + Kernel.warn(color("WARNING: #{message}", :yellow)) end def self.warn_deprecated(message) - stderr.puts(color("DEPRECATED: #{message}", :yellow)) + Kernel.warn(color("DEPRECATED: #{message}", :yellow)) end - def self.abort(message) - Kernel.abort(color("ERROR: #{message}", :red)) + def self.abort(message, exit_status = ExitCode::ERROR_DEFAULT) + Kernel.warn(color("ERROR: #{message}", :red)) + exit(exit_status) end def self.verbose_mode(verbose) @@ -59,13 +56,22 @@ def self.debug(prefix, message, sensitive_data_pattern: nil) return unless verbose filtered_message = hide_sensitive_data(message, sensitive_data_pattern) - stderr.puts("\n[#{color(prefix, :red)}] #{filtered_message}") + Kernel.warn("\n[#{color(prefix, :red)}] #{filtered_message}") end def self.should_hide_output? tmp_stderr && !verbose end + def self.cmd(*cmd_to_run, capture_stderr: false) + output, status = capture_stderr ? Open3.capture2e(*cmd_to_run) : Open3.capture2(*cmd_to_run) + + { + output: output, + success: status.success? + } + end + # # Hide sensitive data based on the passed pattern # diff --git a/lib/cpl.rb b/lib/cpl.rb index 0c59cf17..5981a7ad 100644 --- a/lib/cpl.rb +++ b/lib/cpl.rb @@ -6,11 +6,14 @@ require "json" require "jwt" require "net/http" +require "open3" require "pathname" require "tempfile" require "thor" require "yaml" +require_relative "constants/exit_code" + # We need to require base before all commands, since the commands inherit from it require_relative "command/base" @@ -59,9 +62,9 @@ def self.check_cpln_version # rubocop:disable Metrics/MethodLength @checked_cpln_version = true - result = `cpln --version 2>/dev/null` - if $CHILD_STATUS.success? - data = JSON.parse(result) + result = ::Shell.cmd("cpln", "--version", capture_stderr: true) + if result[:success] + data = JSON.parse(result[:output]) version = data["npm"] min_version = Cpl::MIN_CPLN_VERSION @@ -79,10 +82,10 @@ def self.check_cpl_version # rubocop:disable Metrics/MethodLength @checked_cpl_version = true - result = `gem search ^cpl$ --remote 2>/dev/null` - return unless $CHILD_STATUS.success? + result = ::Shell.cmd("gem", "search", "^cpl$", "--remote", capture_stderr: true) + return unless result[:success] - matches = result.match(/cpl \((.+)\)/) + matches = result[:output].match(/cpl \((.+)\)/) return unless matches version = Cpl::VERSION @@ -223,5 +226,5 @@ def self.show_info_header(config) # rubocop:disable Metrics/MethodLength # nice Ctrl+C trap "INT" do puts - exit(1) + exit(ExitCode::INTERRUPT) end diff --git a/spec/cassettes/Command_CleanupImages/deletes_images.yml b/spec/cassettes/Command_CleanupImages/deletes_images.yml deleted file mode 100644 index 8108cc2d..00000000 --- a/spec/cassettes/Command_CleanupImages/deletes_images.yml +++ /dev/null @@ -1,323 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-3:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-3","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-3:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-3","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-3:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-3","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-3:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-3","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-3:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-3","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-3:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-3","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-3:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-3","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-3:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-3","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-3:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-3:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-3:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-3","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-3:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-3","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-3:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-3:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-3:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-3","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-3:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-3","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-3:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-3","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-3:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-3","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-3:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-3","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-3 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-3","description":"my-app-test-3","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-3"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-3/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-3/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:508_149ba15 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:509_1ddaddb - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:510_ad671e6 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:511_7ef99dd - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:512_346384f - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:513_ec7930a - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_CleanupImages/displays_empty_message.yml b/spec/cassettes/Command_CleanupImages/displays_empty_message.yml deleted file mode 100644 index 0ef4a6b7..00000000 --- a/spec/cassettes/Command_CleanupImages/displays_empty_message.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-2"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-2:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-2","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-2:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-2","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-2:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-2","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-2:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-2","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-2:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-2","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-2:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-2","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-2:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-2","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-2:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-2","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-2:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-2","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-2:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-2","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-2:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-2","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-2:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-2","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-2:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-2","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-2:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-2","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-2:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-2","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-2:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-2","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-2:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-2","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-2:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-2","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-2:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-2:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-2","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-2"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-2 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-2","description":"my-app-test-2","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-2"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-2/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-2/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_days.yml b/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_days.yml deleted file mode 100644 index 537b91c5..00000000 --- a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_days.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-5"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-5:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-5","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-5:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-5","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-5:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-5","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-5:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-5","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-5:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-5","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-5:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-5","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-5:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-5","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-5:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-5","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-5:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-5","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-5:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-5","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-5:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-5","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-5:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-5","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-5:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-5","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-5:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-5","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-5:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-5","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-5:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-5","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-5:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-5","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-5:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-5","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-5:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-5:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-5","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-5"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-5 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-5","description":"my-app-test-5","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-5"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-5/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-5/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity.yml b/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity.yml deleted file mode 100644 index 6415f736..00000000 --- a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-4"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-4:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-4","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-4:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-4","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-4:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-4","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-4:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-4","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-4:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-4","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-4:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-4","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-4:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-4","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-4:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-4","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-4:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-4","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-4:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-4","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-4:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-4","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-4:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-4","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-4:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-4","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-4:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-4","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-4:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-4","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-4:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-4","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-4:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-4","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-4:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-4","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-4:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-4:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-4","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-4"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-4 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-4","description":"my-app-test-4","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-4"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-4/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-4/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity_and_days.yml b/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity_and_days.yml deleted file mode 100644 index be6ff504..00000000 --- a/spec/cassettes/Command_CleanupImages/lists_images_to_delete_based_on_max_quantity_and_days.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-3:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-3","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-3:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-3","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-3:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-3","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-3:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-3","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-3:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-3","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-3:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-3","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-3:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-3","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-3:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-3","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-3:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-3:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-3:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-3","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-3:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-3","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-3:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-3:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-3:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-3","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-3:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-3","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-3:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-3","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-3:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-3","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-3:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-3","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-3 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-3","description":"my-app-test-3","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-3"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-3/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-3/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_CleanupImages/skips_delete_confirmation.yml b/spec/cassettes/Command_CleanupImages/skips_delete_confirmation.yml deleted file mode 100644 index 8108cc2d..00000000 --- a/spec/cassettes/Command_CleanupImages/skips_delete_confirmation.yml +++ /dev/null @@ -1,323 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/image/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - df3147d4-da6c-4596-a81b-ebd4f3dc3ddb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "14145" - Date: - - Wed, 23 Aug 2023 20:10:27 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"image","id":"0da7d1c4-64de-45ae-aeaa-26dd4419c57d","name":"my-app-test-3:508_149ba15","version":1,"tags":{},"created":"2023-08-02T08:35:20.291Z","lastModified":"2023-08-02T08:35:20.291Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:508_149ba15"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"508_149ba15","repository":"my-app-test-3","digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","manifest":{"config":{"size":13244,"digest":"sha256:2f146661eb7bd864cdab8eec96f16fdbafcad0ae81b8a15ccbeaa96fcfaa6fd2","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"95ab6ac1-d712-4029-87ee-8491930e9bff","name":"my-app-test-3:509_1ddaddb","version":1,"tags":{},"created":"2023-08-03T08:50:12.529Z","lastModified":"2023-08-03T08:50:12.529Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:509_1ddaddb"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"509_1ddaddb","repository":"my-app-test-3","digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","manifest":{"config":{"size":13242,"digest":"sha256:3d07633e3d84b07bc93f19ab62b2a5ce61938c6ea605da54c6ccfcf748c0ec65","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"4059c6f1-e65d-410c-a39a-1400c91f9a5d","name":"my-app-test-3:510_ad671e6","version":1,"tags":{},"created":"2023-08-04T01:17:29.790Z","lastModified":"2023-08-04T01:17:29.790Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:510_ad671e6"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"510_ad671e6","repository":"my-app-test-3","digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","manifest":{"config":{"size":13245,"digest":"sha256:96cba8fbe68cf07ca3d4aa3627e894380b40c029da586bd6959cdaa9b3c392b0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"ac417ae4-163f-4d83-a2bb-8ae6b3b2ff2b","name":"my-app-test-3:511_7ef99dd","version":1,"tags":{},"created":"2023-08-05T02:51:14.510Z","lastModified":"2023-08-05T02:51:14.510Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:511_7ef99dd"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"511_7ef99dd","repository":"my-app-test-3","digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","manifest":{"config":{"size":13243,"digest":"sha256:f6bf47ac7f7f465bca9be5096194fe5b7feadb72e04a828c51d80e850ec2d8b5","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"e255f381-72ae-45fa-9f10-d663d30cc9fe","name":"my-app-test-3:512_346384f","version":1,"tags":{},"created":"2023-08-06T03:08:27.452Z","lastModified":"2023-08-06T03:08:27.452Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:512_346384f"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"512_346384f","repository":"my-app-test-3","digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","manifest":{"config":{"size":13244,"digest":"sha256:f74c1356aa9269433225abbb471641d2ed0ff0ce7d8c7e598a2a365bf5db7e96","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"8f27c41f-ae52-4bb2-8a52-9ab275eaada0","name":"my-app-test-3:513_ec7930a","version":1,"tags":{},"created":"2023-08-07T13:20:18.633Z","lastModified":"2023-08-07T13:20:18.633Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:513_ec7930a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"513_ec7930a","repository":"my-app-test-3","digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","manifest":{"config":{"size":13244,"digest":"sha256:166fe9a5e58223d4af10ca2c551ac3c3285f0b965052438acbc8c445003befdd","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"1c46ab85-aeda-4fc3-b63a-59e6b6f5da15","name":"my-app-test-3:514_b54466b","version":1,"tags":{},"created":"2023-08-11T09:48:28.880Z","lastModified":"2023-08-11T09:48:28.880Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:514_b54466b"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"514_b54466b","repository":"my-app-test-3","digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","manifest":{"config":{"size":13246,"digest":"sha256:d908860d2a06e1e65155012abe68bf4ad39dadd032940813c9abec8f3312c545","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"269cbb32-8b2a-4f5a-91e5-8edff843ecd2","name":"my-app-test-3:515_515b553","version":1,"tags":{},"created":"2023-08-12T21:56:54.017Z","lastModified":"2023-08-12T21:56:54.017Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:515_515b553"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"515_515b553","repository":"my-app-test-3","digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","manifest":{"config":{"size":13243,"digest":"sha256:6338052bafbfb837ce3382496a1673ee20955e03f9352ef7d9622a84fbcb7063","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"16126f5f-fd5d-4952-a91b-6562346fb0bd","name":"my-app-test-3:516_8b89e50","version":1,"tags":{},"created":"2023-08-13T11:02:45.965Z","lastModified":"2023-08-13T11:02:45.965Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:516_8b89e50"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"516_8b89e50","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"f34ae027-6ad1-4e88-a744-025a6157725d","name":"my-app-test-3:517_1240864","version":1,"tags":{},"created":"2023-08-14T18:44:32.991Z","lastModified":"2023-08-14T18:44:32.991Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:517_1240864"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"517_1240864","repository":"my-app-test-3","digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","manifest":{"config":{"size":13244,"digest":"sha256:f4d59f7f7278fe3ccebbcaa3de75fb5c8d8221bdcce46c87c8a7b0fc10f3dfeb","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"573d25fe-0506-4cef-9574-77a98607380b","name":"my-app-test-3:518_9d24129","version":1,"tags":{},"created":"2023-08-15T19:20:05.518Z","lastModified":"2023-08-15T19:20:05.518Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:518_9d24129"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"518_9d24129","repository":"my-app-test-3","digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","manifest":{"config":{"size":13246,"digest":"sha256:0fd398fcae2a30f477e28fc9465737eda95d4943ed2fa79c1fdbb60ab4f02df3","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2e864a35-1676-4fba-bfc2-6c1de25b5b58","name":"my-app-test-3:519_ecbbfe4","version":1,"tags":{},"created":"2023-08-16T19:39:35.153Z","lastModified":"2023-08-16T19:39:35.153Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:519_ecbbfe4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"519_ecbbfe4","repository":"my-app-test-3","digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","manifest":{"config":{"size":13245,"digest":"sha256:e05557ab2ce92f5f58568576d964cbc6442273a2e6d1fb5497c7e3fdbd839e14","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"daca0716-8115-4817-ac2f-5b13f4d2b9cf","name":"my-app-test-3:520_d04714d","version":1,"tags":{},"created":"2023-08-17T19:55:23.643Z","lastModified":"2023-08-17T19:55:23.643Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:520_d04714d"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"520_d04714d","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b3c04a3-e5be-4697-b1a6-988ddac3e87d","name":"my-app-test-3:521_3d0a5ca","version":1,"tags":{},"created":"2023-08-18T20:11:11.931Z","lastModified":"2023-08-18T20:11:11.931Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:521_3d0a5ca"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"521_3d0a5ca","repository":"my-app-test-3","digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","manifest":{"config":{"size":13241,"digest":"sha256:bdee7c06ec6df6046a94f5a6834d0bf5706cd5d345fb9d3dfc5c024b88a3082d","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"66cbd28b-fe44-43bd-806e-6b52410058f8","name":"my-app-test-3:522_6917008","version":1,"tags":{},"created":"2023-08-19T20:33:37.967Z","lastModified":"2023-08-19T20:33:37.967Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:522_6917008"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"522_6917008","repository":"my-app-test-3","digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","manifest":{"config":{"size":13243,"digest":"sha256:7f75e124a25d146b141621ef1118acda9ddacba837c72f2dfe51ed1bc0d16867","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"fbf16341-54aa-43d1-8f42-f6eae5706e21","name":"my-app-test-3:523_eefdff4","version":1,"tags":{},"created":"2023-08-20T20:52:05.919Z","lastModified":"2023-08-20T20:52:05.919Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:523_eefdff4"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"523_eefdff4","repository":"my-app-test-3","digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","manifest":{"config":{"size":13241,"digest":"sha256:78f60357a4e9dbc7e10f26da368dc4eb211c3d7bd769d77fab7b4fa1c32914c0","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"0ef6b34e-5dbc-45fb-a01e-3d87e8a462b6","name":"my-app-test-3:524_916b671","version":1,"tags":{},"created":"2023-08-21T11:17:45.818Z","lastModified":"2023-08-21T11:17:45.818Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:524_916b671"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"524_916b671","repository":"my-app-test-3","digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","manifest":{"config":{"size":13244,"digest":"sha256:7e56bdbccd8c18eba0e0a88f08539bd4995c2e0dab1642faab0de1bf2f245c8f","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"2b7a5b3e-7191-41d3-a462-d36ee62e27a6","name":"my-app-test-3:525_173932e","version":1,"tags":{},"created":"2023-08-22T16:36:04.338Z","lastModified":"2023-08-22T16:36:04.338Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:525_173932e"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"525_173932e","repository":"my-app-test-3","digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","manifest":{"config":{"size":13246,"digest":"sha256:5b09cf211c0d36927b8b34ec5c6f2c5d369737a740bb1453290b801eb23c4bc8","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}},{"kind":"image","id":"99ee645a-6eb0-4880-bcf8-711525ec734e","name":"my-app-test-3:526_ae71d4a","version":1,"tags":{},"created":"2023-08-23T17:59:54.682Z","lastModified":"2023-08-23T17:59:54.682Z","links":[{"rel":"self","href":"/org/my-org-staging/image/my-app-test-3:526_ae71d4a"},{"rel":"org","href":"/org/my-org-staging"}],"tag":"526_ae71d4a","repository":"my-app-test-3","digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","manifest":{"config":{"size":13246,"digest":"sha256:824f7f16ba2685900f01bf276e24db7dc87e4d828a6fa8153da9e764f7050b53","mediaType":"application/vnd.docker.container.image.v1+json"},"mediaType":"application/vnd.docker.distribution.manifest.v2+json","schemaVersion":2}}],"links":[{"rel":"self","href":"/q/Fjt_aapGRraW5kZWltYWdlZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4GjaHByb3BlcnR5anJlcG9zaXRvcnlib3BhPWV2YWx1ZW5oaWNoZWUtc3RhZ2luZ2djb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lbmhpY2hlZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"image","spec":{"match":"all","terms":[{"property":"repository","op":"=","value":"my-app-test-3"}]},"fetch":"items"}}' - recorded_at: Wed, 23 Aug 2023 20:10:28 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-test-3 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - aa0ac632-94f7-4519-aabf-8c3f22a73d9a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "614" - Date: - - Wed, 23 Aug 2023 20:10:29 GMT - X-Envoy-Upstream-Service-Time: - - "17" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"gvc","id":"0d51ba8a-9f7c-4c09-a7ab-097fabe76ea0","name":"my-app-test-3","description":"my-app-test-3","version":1,"tags":{},"created":"2023-01-23T07:04:33.705Z","lastModified":"2023-08-10T01:55:49.246Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-test-3"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-test-3/workload"},{"rel":"identity","href":"/org/my-org-staging/gvc/my-app-test-3/identity"}],"alias":"37te1a1c441e8","spec":{"env":[],"staticPlacement":{"locationLinks":["/org/my-org-staging/location/aws-us-east-2"]}},"status":{}}' - recorded_at: Wed, 23 Aug 2023 20:10:30 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:508_149ba15 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:509_1ddaddb - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:510_ad671e6 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:511_7ef99dd - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:512_346384f - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/image/my-app-test-3:513_ec7930a - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 596b0fab-2307-4281-8fd0-44181e973cb7 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 24 Aug 2023 17:35:24 GMT - X-Envoy-Upstream-Service-Time: - - "4" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 24 Aug 2023 17:35:25 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_Maintenance/displays_error_if_domain_is_not_found.yml b/spec/cassettes/Command_Maintenance/displays_error_if_domain_is_not_found.yml deleted file mode 100644 index a62412e4..00000000 --- a/spec/cassettes/Command_Maintenance/displays_error_if_domain_is_not_found.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 0ec032eb-7601-4778-b7e8-1ca16ed5bd11 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2951" - Date: - - Thu, 18 May 2023 16:48:38 GMT - X-Envoy-Upstream-Service-Time: - - "94" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"locations":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"z37ANVVP+r3pSuLzfVDjN1tx07o"}}]}' - recorded_at: Thu, 18 May 2023 16:48:39 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_Maintenance/displays_off_if_maintenance_mode_is_disabled.yml b/spec/cassettes/Command_Maintenance/displays_off_if_maintenance_mode_is_disabled.yml deleted file mode 100644 index 0fb846bb..00000000 --- a/spec/cassettes/Command_Maintenance/displays_off_if_maintenance_mode_is_disabled.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - b69df380-4b42-4203-a357-531737bcb3c8 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2059" - Date: - - Thu, 18 May 2023 16:56:11 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:56:12 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_Maintenance/displays_on_if_maintenance_mode_is_enabled.yml b/spec/cassettes/Command_Maintenance/displays_on_if_maintenance_mode_is_enabled.yml deleted file mode 100644 index 8d7dffd6..00000000 --- a/spec/cassettes/Command_Maintenance/displays_on_if_maintenance_mode_is_enabled.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 42603a33-c1e1-43f2-9a17-5a324335eec0 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2071" - Date: - - Thu, 18 May 2023 16:58:42 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:58:43 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOff/disables_maintenance_mode.yml b/spec/cassettes/Command_MaintenanceOff/disables_maintenance_mode.yml deleted file mode 100644 index ba252e11..00000000 --- a/spec/cassettes/Command_MaintenanceOff/disables_maintenance_mode.yml +++ /dev/null @@ -1,603 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 302b1bc8-ded3-4a08-8b54-f28e85334711 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2071" - Date: - - Thu, 18 May 2023 20:55:37 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":2,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-05-18T18:41:15.000Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"RW8jOyzb2aSKc9PizGJDnZ1U+B8"}}]}' - recorded_at: Thu, 18 May 2023 20:55:37 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - e5fc3c16-8032-45ce-b09a-76bf2681fbc6 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1404" - Date: - - Thu, 18 May 2023 20:55:38 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:38 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 4c75a6a2-dcb0-4fd8-be60-45025a57d11a - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1519" - Date: - - Thu, 18 May 2023 20:55:39 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-18T18:41:18.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:39 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-18T18:41:18.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 35645aa7-d2f7-483e-98c6-4255868d851d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1520" - Date: - - Thu, 18 May 2023 20:55:39 GMT - X-Envoy-Upstream-Service-Time: - - "12" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":3,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-18T20:55:39.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:39 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - ef4becf3-133c-4d6d-8ab6-1b8e6995ec55 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1241" - Date: - - Thu, 18 May 2023 20:55:40 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-18T18:41:17.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:40 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-18T18:41:17.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 8f78d011-90f0-4b01-8f51-76c2ca7e693e - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1242" - Date: - - Thu, 18 May 2023 20:55:40 GMT - X-Envoy-Upstream-Service-Time: - - "8" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":3,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-18T20:55:40.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:40 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - a853e347-0967-48a3-9adf-4b574bf240d2 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1356" - Date: - - Thu, 18 May 2023 20:55:41 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-18T18:41:16.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:41 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-18T18:41:16.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 30e01192-7b8b-4983-a2c3-686b654c7c16 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1357" - Date: - - Thu, 18 May 2023 20:55:41 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":3,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-18T20:55:41.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:41 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - e8a97f5f-130b-4fa7-b0f1-c82b2094bc92 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1531" - Date: - - Thu, 18 May 2023 20:55:42 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://postgres-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":2,"expectedDeploymentVersion":3,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T20:55:39.000Z","ksvcStatus":{"Available":{"status":"True","lastTransitionTime":"2023-05-18T20:55:39.000Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable"},"Progressing":{"status":"True","lastTransitionTime":"2023-05-18T20:55:39.000Z","message":"ReplicaSet \"postgres-57f9979cfc\" has successfully progressed.","reason":"NewReplicaSetAvailable"}}},"ready":true,"versions":[{"message":"","ready":true,"containers":{"postgres":{"name":"postgres","image":"postgres:13.8-alpine","resources":{"memory":128,"cpu":50,"replicas":1,"replicasReady":1},"message":"","ready":true}},"created":"2023-05-18T20:55:39.000Z","workload":3}]},"lastModified":"2023-05-18T20:55:39.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"}]}' - recorded_at: Thu, 18 May 2023 20:55:42 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 45d20b61-0b98-404b-b013-d006b9e636c1 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1498" - Date: - - Thu, 18 May 2023 20:55:43 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://redis-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":2,"expectedDeploymentVersion":3,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T20:55:40.000Z","ksvcStatus":{"Available":{"status":"True","lastTransitionTime":"2023-05-18T20:55:40.000Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable"},"Progressing":{"status":"True","lastTransitionTime":"2023-05-18T20:55:40.000Z","message":"ReplicaSet \"redis-774c4799d4\" has successfully progressed.","reason":"NewReplicaSetAvailable"}}},"ready":true,"versions":[{"message":"","ready":true,"containers":{"redis":{"name":"redis","image":"redis:6.2.6","resources":{"memory":128,"cpu":50,"replicas":1,"replicasReady":1},"message":"","ready":true}},"created":"2023-05-18T20:55:40.000Z","workload":3}]},"lastModified":"2023-05-18T20:55:40.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"}]}' - recorded_at: Thu, 18 May 2023 20:55:43 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 0fa1bc63-8dbb-457a-a435-1e21d90ac353 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1549" - Date: - - Thu, 18 May 2023 20:55:44 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://rails-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":2,"expectedDeploymentVersion":3,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T20:55:41.000Z","ksvcStatus":{"Progressing":{"status":"True","lastTransitionTime":"2023-05-18T20:55:41.000Z","message":"ReplicaSet \"rails-685f76769\" has successfully progressed.","reason":"NewReplicaSetAvailable"},"Available":{"status":"True","lastTransitionTime":"2023-05-18T20:55:41.000Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable"}}},"ready":true,"versions":[{"message":"","ready":true,"containers":{"rails":{"name":"rails","image":"/org/my-org-staging/image/my-app-staging:5_1234567890AAABBBCCC","resources":{"memory":512,"cpu":300,"replicas":1,"replicasReady":1},"message":"","ready":true}},"created":"2023-05-18T20:55:41.000Z","workload":3}]},"lastModified":"2023-05-18T20:55:41.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}]}' - recorded_at: Thu, 18 May 2023 20:55:44 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/domain/my-app-staging.example.com - body: - encoding: UTF-8 - string: '{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":2,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-05-18T18:41:15.000Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"RW8jOyzb2aSKc9PizGJDnZ1U+B8"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - fe343ebe-cdc1-4703-a8a1-1b0598802b6b - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "865" - Date: - - Thu, 18 May 2023 20:55:45 GMT - X-Envoy-Upstream-Service-Time: - - "14" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":3,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-05-18T20:55:45.000Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false}}' - recorded_at: Thu, 18 May 2023 20:55:45 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - a73ddcb6-34a3-4929-898c-507c1e448204 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1404" - Date: - - Thu, 18 May 2023 20:55:46 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:46 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 125facd8-00c8-949a-b15e-13b6bf4e2a91 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1403" - Date: - - Thu, 18 May 2023 20:55:46 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":3,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T20:55:46.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 20:55:46 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 18e8ed5e-cb53-46a6-a926-9c99b6ed6bda - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1231" - Date: - - Thu, 18 May 2023 20:55:47 GMT - X-Envoy-Upstream-Service-Time: - - "9" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://maintenance-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":2,"expectedDeploymentVersion":3,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T20:55:46.000Z"},"ready":false,"versions":[{"message":"Thisworkload location is deactivated because suspend is set to true","ready":false,"created":"2023-05-18T20:55:46.000Z","containers":{"maintenance":{"image":"shakacode/maintenance-mode","name":"maintenance","ready":false,"resources":{"replicas":0,"memory":128,"cpu":50}}},"workload":3}]},"lastModified":"2023-05-18T20:55:46.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}]}' - recorded_at: Thu, 18 May 2023 20:55:47 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOff/displays_error_if_domain_is_not_found.yml b/spec/cassettes/Command_MaintenanceOff/displays_error_if_domain_is_not_found.yml deleted file mode 100644 index a62412e4..00000000 --- a/spec/cassettes/Command_MaintenanceOff/displays_error_if_domain_is_not_found.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 0ec032eb-7601-4778-b7e8-1ca16ed5bd11 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2951" - Date: - - Thu, 18 May 2023 16:48:38 GMT - X-Envoy-Upstream-Service-Time: - - "94" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"locations":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"z37ANVVP+r3pSuLzfVDjN1tx07o"}}]}' - recorded_at: Thu, 18 May 2023 16:48:39 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOff/displays_error_if_maintenance_workload_is_not_found.yml b/spec/cassettes/Command_MaintenanceOff/displays_error_if_maintenance_workload_is_not_found.yml deleted file mode 100644 index ed8adbd0..00000000 --- a/spec/cassettes/Command_MaintenanceOff/displays_error_if_maintenance_workload_is_not_found.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - b69df380-4b42-4203-a357-531737bcb3c8 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2071" - Date: - - Thu, 18 May 2023 16:56:11 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:56:12 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 404 - message: Not Found - headers: - X-Request-Id: - - 98690e01-2b20-44b7-bbd2-178a3e79a812 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "145" - Date: - - Thu, 18 May 2023 19:17:51 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"message":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance does not exist","status":404,"id":"98690e01-2b20-44b7-bbd2-178a3e79a812"}' - recorded_at: Thu, 18 May 2023 19:17:51 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOff/does_nothing_if_maintenance_mode_is_already_disabled.yml b/spec/cassettes/Command_MaintenanceOff/does_nothing_if_maintenance_mode_is_already_disabled.yml deleted file mode 100644 index 0fb846bb..00000000 --- a/spec/cassettes/Command_MaintenanceOff/does_nothing_if_maintenance_mode_is_already_disabled.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - b69df380-4b42-4203-a357-531737bcb3c8 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2059" - Date: - - Thu, 18 May 2023 16:56:11 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:56:12 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOn/displays_error_if_domain_is_not_found.yml b/spec/cassettes/Command_MaintenanceOn/displays_error_if_domain_is_not_found.yml deleted file mode 100644 index a62412e4..00000000 --- a/spec/cassettes/Command_MaintenanceOn/displays_error_if_domain_is_not_found.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 0ec032eb-7601-4778-b7e8-1ca16ed5bd11 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2951" - Date: - - Thu, 18 May 2023 16:48:38 GMT - X-Envoy-Upstream-Service-Time: - - "94" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"locations":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/test","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"z37ANVVP+r3pSuLzfVDjN1tx07o"}}]}' - recorded_at: Thu, 18 May 2023 16:48:39 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOn/displays_error_if_maintenance_workload_is_not_found.yml b/spec/cassettes/Command_MaintenanceOn/displays_error_if_maintenance_workload_is_not_found.yml deleted file mode 100644 index 38f5d062..00000000 --- a/spec/cassettes/Command_MaintenanceOn/displays_error_if_maintenance_workload_is_not_found.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - b69df380-4b42-4203-a357-531737bcb3c8 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2059" - Date: - - Thu, 18 May 2023 16:56:11 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:56:12 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 404 - message: Not Found - headers: - X-Request-Id: - - 98690e01-2b20-44b7-bbd2-178a3e79a812 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "145" - Date: - - Thu, 18 May 2023 19:17:51 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"message":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance does not exist","status":404,"id":"98690e01-2b20-44b7-bbd2-178a3e79a812"}' - recorded_at: Thu, 18 May 2023 19:17:51 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOn/does_nothing_if_maintenance_mode_is_already_enabled.yml b/spec/cassettes/Command_MaintenanceOn/does_nothing_if_maintenance_mode_is_already_enabled.yml deleted file mode 100644 index 8d7dffd6..00000000 --- a/spec/cassettes/Command_MaintenanceOn/does_nothing_if_maintenance_mode_is_already_enabled.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 42603a33-c1e1-43f2-9a17-5a324335eec0 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2071" - Date: - - Thu, 18 May 2023 16:58:42 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 16:58:43 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceOn/enables_maintenance_mode.yml b/spec/cassettes/Command_MaintenanceOn/enables_maintenance_mode.yml deleted file mode 100644 index c8d7f3bd..00000000 --- a/spec/cassettes/Command_MaintenanceOn/enables_maintenance_mode.yml +++ /dev/null @@ -1,603 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/domain - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 73d9eb9c-d189-4d6f-ac4e-f4b4fc95c97d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2059" - Date: - - Thu, 18 May 2023 18:41:12 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"domain","links":[{"rel":"self","href":"/org/my-org-staging/domain"}],"items":[{"kind":"domain","id":"9f5762c0-5afe-4214-a57f-df9eef722fb2","name":"example.com","description":"example.com","version":1,"tags":{},"created":"2023-02-14T19:08:15.563Z","lastModified":"2023-02-14T19:08:15.563Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"minProtocolVersion":"TLSV1_2"},"number":443,"protocol":"http2"}],"dnsMode":"cname","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[],"fingerprint":"l9Fw4VUO7kr8CvBlt4zaMCqXZ0w"}},{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}]}' - recorded_at: Thu, 18 May 2023 18:41:12 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - afc61fa6-7c40-433d-8635-46da0119f451 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1403" - Date: - - Thu, 18 May 2023 18:41:13 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":1,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T00:18:55.334Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:13 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - e7583c7b-1401-4903-832d-31c1f0ad2232 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1403" - Date: - - Thu, 18 May 2023 18:41:13 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":1,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T00:18:55.334Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:13 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":1,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T00:18:55.334Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - dc2f6cd4-6c8c-460a-909e-8207eae90fd4 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1404" - Date: - - Thu, 18 May 2023 18:41:13 GMT - X-Envoy-Upstream-Service-Time: - - "40" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:13 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 508caad0-74a8-49f1-8901-b693d4f52162 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1561" - Date: - - Thu, 18 May 2023 18:41:14 GMT - X-Envoy-Upstream-Service-Time: - - "8" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://maintenance-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":1,"expectedDeploymentVersion":2,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T18:41:13.000Z","ksvcStatus":{"Available":{"status":"True","lastTransitionTime":"2023-05-18T18:41:13.000Z","message":"Deployment has minimum availability.","reason":"MinimumReplicasAvailable"},"Progressing":{"status":"True","lastTransitionTime":"2023-05-18T18:41:13.000Z","message":"ReplicaSet \"maintenance-7dfcb4864c\" has successfully progressed.","reason":"NewReplicaSetAvailable"}}},"ready":true,"versions":[{"message":"","ready":true,"containers":{"maintenance":{"name":"maintenance","image":"shakacode/maintenance-mode","resources":{"memory":128,"cpu":50,"replicas":1,"replicasReady":1},"message":"","ready":true}},"created":"2023-05-18T18:41:13.000Z","workload":2}]},"lastModified":"2023-05-18T18:41:13.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}]}' - recorded_at: Thu, 18 May 2023 18:41:14 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/domain/my-app-staging.example.com - body: - encoding: UTF-8 - string: '{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":1,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-02-14T19:11:01.086Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false},"status":{"status":"ready","warning":"","endpoints":[{"url":"https://my-app-staging.example.com/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}],"locations":[{"name":"aws-us-east-2","certificateStatus":"ready"}],"fingerprint":"NLMYcpJdwRpol0szlbj/arbN83I"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - bd009ffc-2be5-4dca-ab95-3b73ea0fc64c - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "871" - Date: - - Thu, 18 May 2023 18:41:15 GMT - X-Envoy-Upstream-Service-Time: - - "21" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"domain","id":"4cad1bd2-261f-47db-aa9c-781704201440","name":"my-app-staging.example.com","description":"my-app-staging.example.com","version":2,"tags":{},"created":"2023-02-14T19:11:01.086Z","lastModified":"2023-05-18T18:41:15.000Z","links":[{"rel":"self","href":"/org/my-org-staging/domain/my-app-staging.example.com"},{"rel":"org","href":"/org/my-org-staging"}],"spec":{"ports":[{"tls":{"cipherSuites":["ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-ECDSA-CHACHA20-POLY1305","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES256-GCM-SHA384","ECDHE-RSA-CHACHA20-POLY1305","ECDHE-RSA-AES128-GCM-SHA256","AES256-GCM-SHA384","AES128-GCM-SHA256"],"serverCertificate":{},"minProtocolVersion":"TLSV1_2"},"number":443,"routes":[{"prefix":"/","workloadLink":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"}],"protocol":"http2"}],"dnsMode":"ns","acceptAllHosts":false}}' - recorded_at: Thu, 18 May 2023 18:41:15 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 4590221b-2047-429a-95ce-258f841c4974 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1357" - Date: - - Thu, 18 May 2023 18:41:16 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-02T16:26:51.107Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:16 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-02T16:26:51.107Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 26fbc57b-6f1b-48ca-9c5c-343bce7a15ba - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1356" - Date: - - Thu, 18 May 2023 18:41:16 GMT - X-Envoy-Upstream-Service-Time: - - "7" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"c8c1da11-dd92-41d7-82b8-60fe703fdc56","name":"rails","description":"rails","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:51.107Z"},"created":"2023-05-02T16:26:51.107Z","lastModified":"2023-05-18T18:41:16.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"LOG_LEVEL","value":"debug"}],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:16 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 290eb33c-dbc9-4a28-80e4-83545f5bfd94 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1242" - Date: - - Thu, 18 May 2023 18:41:17 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-02T16:26:49.653Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:17 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-02T16:26:49.653Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - f05f9ebb-7c2d-4f3e-98c3-8bde659c7d18 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1241" - Date: - - Thu, 18 May 2023 18:41:17 GMT - X-Envoy-Upstream-Service-Time: - - "81" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"b6fed3ba-0974-4e87-890f-aa2f0d7180ab","name":"redis","description":"redis","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:49.653Z"},"created":"2023-05-02T16:26:49.653Z","lastModified":"2023-05-18T18:41:17.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","name":"redis","image":"redis:6.2.6","ports":[{"number":6379,"protocol":"tcp"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://redis-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"redis.my-app-staging.cpln.local","canonicalEndpoint":"https://redis-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:17 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 902a8033-2990-47a4-a70b-3840282142e6 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1520" - Date: - - Thu, 18 May 2023 18:41:18 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-02T16:26:46.970Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:18 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":1,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-02T16:26:46.970Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 7d9d330e-43ef-44af-a2d2-97621e258928 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1519" - Date: - - Thu, 18 May 2023 18:41:18 GMT - X-Envoy-Upstream-Service-Time: - - "89" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"8d115fba-cb87-48da-9777-19266c2965e2","name":"postgres","description":"postgres","version":2,"tags":{"cpln/deployTimestamp":"2023-05-02T16:26:46.970Z"},"created":"2023-05-02T16:26:46.970Z","lastModified":"2023-05-18T18:41:18.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PGUSER","value":"postgres"},{"name":"POSTGRES_PASSWORD","value":"password123"},{"name":"POSTGRES_USER","value":"postgres"}],"name":"postgres","image":"postgres:13.8-alpine","ports":[{"number":5432,"protocol":"tcp"}],"memory":"128Mi","volumes":[{"uri":"scratch://postgres-vol","path":"/var/lib/postgresql/data","recoveryPolicy":"retain"}],"inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":true,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"internal":{"inboundAllowType":"same-gvc","inboundAllowWorkload":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://postgres-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"postgres.my-app-staging.cpln.local","canonicalEndpoint":"https://postgres-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 18:41:18 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 9d86779c-cc2c-48f7-995e-0e1f7999c902 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1207" - Date: - - Thu, 18 May 2023 18:41:19 GMT - X-Envoy-Upstream-Service-Time: - - "39" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://rails-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":1,"expectedDeploymentVersion":2,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T18:41:18.000Z"},"ready":false,"versions":[{"message":"This workload location is deactivated because suspend is set to true","ready":false,"created":"2023-05-18T18:41:18.000Z","containers":{"rails":{"image":"/org/my-org-staging/image/my-app-staging:1","name":"rails","ready":false,"resources":{"replicas":0,"memory":512,"cpu":300}}},"workload":2}]},"lastModified":"2023-05-18T18:41:18.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails"}]}' - recorded_at: Thu, 18 May 2023 18:41:19 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - da525ec8-e4bc-4f79-8a4e-c05a17077659 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1175" - Date: - - Thu, 18 May 2023 18:41:20 GMT - X-Envoy-Upstream-Service-Time: - - "31" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://redis-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":1,"expectedDeploymentVersion":2,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T18:41:18.000Z"},"ready":false,"versions":[{"message":"This workload location is deactivated because suspend is set to true","ready":false,"created":"2023-05-18T18:41:18.000Z","containers":{"redis":{"image":"redis:6.2.6","name":"redis","ready":false,"resources":{"replicas":0,"memory":128,"cpu":50}}},"workload":2}]},"lastModified":"2023-05-18T18:41:18.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/redis"}]}' - recorded_at: Thu, 18 May 2023 18:41:20 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 0ebab0bb-9f8e-42f2-b9c1-67cff63c1c54 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1205" - Date: - - Thu, 18 May 2023 18:41:21 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"list","itemKind":"deployment","items":[{"name":"aws-us-east-2","status":{"endpoint":"https://postgres-hd66p547bcrpy.aws-us-east-2.controlplane.us/","remote":"https://c304ea723c26c198c51959a2125cb9c9.remote.cpln.io","lastProcessedVersion":1,"expectedDeploymentVersion":2,"internal":{"podStatus":{},"podsValidZone":true,"timestamp":"2023-05-18T18:41:18.000Z"},"ready":false,"versions":[{"message":"This workload location is deactivated because suspend is set to true","ready":false,"created":"2023-05-18T18:41:18.000Z","containers":{"postgres":{"image":"postgres:13.8-alpine","name":"postgres","ready":false,"resources":{"replicas":0,"memory":128,"cpu":50}}},"workload":2}]},"lastModified":"2023-05-18T18:41:18.000Z","kind":"deployment","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment/aws-us-east-2"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"},{"rel":"location","href":"/org/my-org-staging/location/aws-us-east-2"}]}],"links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres/deployment"},{"rel":"workload","href":"/org/my-org-staging/gvc/my-app-staging/workload/postgres"}]}' - recorded_at: Thu, 18 May 2023 18:41:21 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceSetPage/displays_error_if_maintenance_workload_is_not_found.yml b/spec/cassettes/Command_MaintenanceSetPage/displays_error_if_maintenance_workload_is_not_found.yml deleted file mode 100644 index f9525097..00000000 --- a/spec/cassettes/Command_MaintenanceSetPage/displays_error_if_maintenance_workload_is_not_found.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 404 - message: Not Found - headers: - X-Request-Id: - - 98690e01-2b20-44b7-bbd2-178a3e79a812 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "145" - Date: - - Thu, 18 May 2023 19:17:51 GMT - X-Envoy-Upstream-Service-Time: - - "6" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"message":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance does not exist","status":404,"id":"98690e01-2b20-44b7-bbd2-178a3e79a812"}' - recorded_at: Thu, 18 May 2023 19:17:51 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceSetPage/does_nothing_if_maintenance_workload_does_not_use_shakacode_image.yml b/spec/cassettes/Command_MaintenanceSetPage/does_nothing_if_maintenance_workload_does_not_use_shakacode_image.yml deleted file mode 100644 index 61fcdb5a..00000000 --- a/spec/cassettes/Command_MaintenanceSetPage/does_nothing_if_maintenance_workload_does_not_use_shakacode_image.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 9784ba58-6807-4bd6-87a4-ebb1490ff956 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1400" - Date: - - Thu, 18 May 2023 22:28:43 GMT - X-Envoy-Upstream-Service-Time: - - "44" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"wickerlabs/maintenance","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 22:28:43 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_MaintenanceSetPage/sets_page_for_maintenance_mode.yml b/spec/cassettes/Command_MaintenanceSetPage/sets_page_for_maintenance_mode.yml deleted file mode 100644 index 1ebd85b1..00000000 --- a/spec/cassettes/Command_MaintenanceSetPage/sets_page_for_maintenance_mode.yml +++ /dev/null @@ -1,123 +0,0 @@ ---- -http_interactions: - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 9784ba58-6807-4bd6-87a4-ebb1490ff956 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1404" - Date: - - Thu, 18 May 2023 22:28:43 GMT - X-Envoy-Upstream-Service-Time: - - "44" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 22:28:43 GMT - - request: - method: get - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - e0809f8b-7ccf-45fa-85e4-814d8b4a6956 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1404" - Date: - - Thu, 18 May 2023 22:28:43 GMT - X-Envoy-Upstream-Service-Time: - - "5" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":""},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 22:28:43 GMT - - request: - method: patch - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/maintenance - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T18:41:13.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":"https://example.com/maintenance.html"},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - a38d6f1c-c373-48bf-b33a-2c4a17cd640d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "1440" - Date: - - Thu, 18 May 2023 22:28:43 GMT - X-Envoy-Upstream-Service-Time: - - "316" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"workload","id":"a105b63c-e2a4-4ff7-bfa1-eb0545b0d1ae","name":"maintenance","description":"maintenance","version":2,"tags":{"cpln/deployTimestamp":"2023-05-18T00:18:55.334Z"},"created":"2023-05-18T00:18:55.334Z","lastModified":"2023-05-18T22:28:43.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/maintenance/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"50m","env":[{"name":"PAGE_URL","value":"https://example.com/maintenance.html"},{"name":"PORT","value":"3000"}],"name":"maintenance","image":"shakacode/maintenance-mode","ports":[{"number":3000,"protocol":"http"}],"memory":"128Mi","inheritEnv":false}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":60},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":[],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://maintenance-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"maintenance.my-app-staging.cpln.local","canonicalEndpoint":"https://maintenance-hd66p547bcrpy.cpln.app"}}' - recorded_at: Thu, 18 May 2023 22:28:43 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads.yml b/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads.yml deleted file mode 100644 index ea494c70..00000000 --- a/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads.yml +++ /dev/null @@ -1,243 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - d88f44f7-da5d-4dae-91ea-bd36a727c309 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "7052" - Date: - - Mon, 15 May 2023 23:03:19 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"5f8a0b42-82c7-45b2-b14d-d5b3733b41a0","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"8842d7a0-42a3-4e3d-b4ce-04d54afee3bb","name":"rails-run-4137","description":"rails-run-4137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-4137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"a34d8cce-7f9b-4c0d-a144-58fbe29bb2f9","name":"rails-run-5192","description":"rails-run-5192","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-5192.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"c9df16b7-06c6-427c-8e81-bbde933d5926","name":"rails-run-7025","description":"rails-run-7025","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-7025.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app"}}],"links":[{"rel":"self","href":"/q/pCx_mUpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcHJhZmFlbC1zaGFrYWNvZGVlZmV0Y2hlaXRlbXM"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Mon, 15 May 2023 23:03:20 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - da2ce333-6100-4999-9afa-d371a7593f7f - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Mon, 15 May 2023 23:40:09 GMT - X-Envoy-Upstream-Service-Time: - - "62" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Mon, 15 May 2023 23:40:10 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 5343b8c7-50a9-428c-9c30-c1543605ec95 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Mon, 15 May 2023 23:40:10 GMT - X-Envoy-Upstream-Service-Time: - - "25" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Mon, 15 May 2023 23:40:11 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 181c36bd-09d5-4d55-bb55-4b917403c39b - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8255" - Date: - - Wed, 05 Jul 2023 21:43:46 GMT - X-Envoy-Upstream-Service-Time: - - "9" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"51d03e38-ac45-428f-ba61-920951dc14e8","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"9dad9cdc-695e-435d-83e0-2baf8b60bee8","name":"rails-runner-4985","description":"rails-runner-4985","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-4985.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"5fdf6390-ddfb-471f-a837-9260a531d885","name":"rails-runner-5137","description":"rails-runner-5137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-5137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"da472b95-97e5-4060-ab33-1b09d973f9e2","name":"rails-runner-6669","description":"rails-runner-6669","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-6669.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app"}}],"links":[{"rel":"self","href":"/q/DksqTmpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Wed, 05 Jul 2023 21:43:47 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 8d077e40-3ac3-450d-8714-6c91d3156725 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Wed, 05 Jul 2023 22:05:52 GMT - X-Envoy-Upstream-Service-Time: - - "33" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Wed, 05 Jul 2023 22:05:53 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - ef97b02b-56bf-4a2d-b585-bbf6fc432da5 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Wed, 05 Jul 2023 22:05:53 GMT - X-Envoy-Upstream-Service-Time: - - "61" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Wed, 05 Jul 2023 22:05:54 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads_for_all_apps_that_start_with_name.yml b/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads_for_all_apps_that_start_with_name.yml deleted file mode 100644 index 7605e99c..00000000 --- a/spec/cassettes/Command_RunCleanup/deletes_stale_run_workloads_for_all_apps_that_start_with_name.yml +++ /dev/null @@ -1,243 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - cf712142-8ed6-4ea2-a2ef-5061a501dc0d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "3825" - Date: - - Thu, 06 Jul 2023 00:26:12 GMT - X-Envoy-Upstream-Service-Time: - - "1124" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"1e05759b-bab5-4dfb-bd53-912f4144dc09","name":"rails-run-1527","description":"rails-run-1527","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-run-1527.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"bc52342e-de2f-45b4-8a52-20945d5881b5","name":"rails-run-9213","description":"rails-run-9213","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-run-9213.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/Om_bGPpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:13 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - c2037b36-e1bc-4c7b-a79b-663c0f02af75 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "4428" - Date: - - Thu, 06 Jul 2023 00:26:13 GMT - X-Envoy-Upstream-Service-Time: - - "136" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"b297fdc1-2a64-481d-9f8b-03207b306c06","name":"rails-runner-8931","description":"rails-runner-8931","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-runner-8931.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"51b2ee83-ff48-4a62-b20f-17300b2423b6","name":"rails-runner-1273","description":"rails-runner-1273","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-runner-1273.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/-oVQ34pGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:14 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 6efd3bae-8c98-4e03-8ad3-d03d22c96f9e - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:18 GMT - X-Envoy-Upstream-Service-Time: - - "46" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:19 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 2e11892e-e4f0-4079-98e9-073755be223d - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:19 GMT - X-Envoy-Upstream-Service-Time: - - "38" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:20 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - cb4e3876-d98d-4817-af0a-84351c38901f - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:20 GMT - X-Envoy-Upstream-Service-Time: - - "26" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:21 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 85d5184c-48a1-401d-99ec-5849b7426687 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:21 GMT - X-Envoy-Upstream-Service-Time: - - "27" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:22 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/displays_empty_message.yml b/spec/cassettes/Command_RunCleanup/displays_empty_message.yml deleted file mode 100644 index 480319d8..00000000 --- a/spec/cassettes/Command_RunCleanup/displays_empty_message.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 5439c26e-3f70-4b86-9c55-ad0d9020baeb - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2110" - Date: - - Mon, 15 May 2023 23:58:55 GMT - X-Envoy-Upstream-Service-Time: - - "34" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"a34d8cce-7f9b-4c0d-a144-58fbe29bb2f9","name":"rails-run-5192","description":"rails-run-5192","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-5192.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app"}}],"links":[{"rel":"self","href":"/q/pCx_mUpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcHJhZmFlbC1zaGFrYWNvZGVlZmV0Y2hlaXRlbXM"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Mon, 15 May 2023 23:58:56 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - ec9b2c9c-c667-4263-a200-25f43e5debd5 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "2423" - Date: - - Wed, 05 Jul 2023 20:57:27 GMT - X-Envoy-Upstream-Service-Time: - - "59" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"5fdf6390-ddfb-471f-a837-9260a531d885","name":"rails-runner-5137","description":"rails-runner-5137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-5137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app"}}],"links":[{"rel":"self","href":"/q/DksqTmpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Wed, 05 Jul 2023 20:57:28 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads.yml b/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads.yml deleted file mode 100644 index 41a067af..00000000 --- a/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - d88f44f7-da5d-4dae-91ea-bd36a727c309 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "7052" - Date: - - Mon, 15 May 2023 23:03:19 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"5f8a0b42-82c7-45b2-b14d-d5b3733b41a0","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"8842d7a0-42a3-4e3d-b4ce-04d54afee3bb","name":"rails-run-4137","description":"rails-run-4137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-4137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"a34d8cce-7f9b-4c0d-a144-58fbe29bb2f9","name":"rails-run-5192","description":"rails-run-5192","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-5192.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"c9df16b7-06c6-427c-8e81-bbde933d5926","name":"rails-run-7025","description":"rails-run-7025","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-7025.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app"}}],"links":[{"rel":"self","href":"/q/pCx_mUpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcHJhZmFlbC1zaGFrYWNvZGVlZmV0Y2hlaXRlbXM"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Mon, 15 May 2023 23:03:20 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 181c36bd-09d5-4d55-bb55-4b917403c39b - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8255" - Date: - - Wed, 05 Jul 2023 21:43:46 GMT - X-Envoy-Upstream-Service-Time: - - "9" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"51d03e38-ac45-428f-ba61-920951dc14e8","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"9dad9cdc-695e-435d-83e0-2baf8b60bee8","name":"rails-runner-4985","description":"rails-runner-4985","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-4985.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"5fdf6390-ddfb-471f-a837-9260a531d885","name":"rails-runner-5137","description":"rails-runner-5137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-5137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"da472b95-97e5-4060-ab33-1b09d973f9e2","name":"rails-runner-6669","description":"rails-runner-6669","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-6669.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app"}}],"links":[{"rel":"self","href":"/q/DksqTmpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Wed, 05 Jul 2023 21:43:47 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads_for_all_apps_that_start_with_name.yml b/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads_for_all_apps_that_start_with_name.yml deleted file mode 100644 index 7c569ae5..00000000 --- a/spec/cassettes/Command_RunCleanup/lists_stale_run_workloads_for_all_apps_that_start_with_name.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - cf712142-8ed6-4ea2-a2ef-5061a501dc0d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "3825" - Date: - - Thu, 06 Jul 2023 00:26:12 GMT - X-Envoy-Upstream-Service-Time: - - "1124" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"1e05759b-bab5-4dfb-bd53-912f4144dc09","name":"rails-run-1527","description":"rails-run-1527","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-run-1527.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"bc52342e-de2f-45b4-8a52-20945d5881b5","name":"rails-run-9213","description":"rails-run-9213","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-run-9213.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/Om_bGPpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:13 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - c2037b36-e1bc-4c7b-a79b-663c0f02af75 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "4428" - Date: - - Thu, 06 Jul 2023 00:26:13 GMT - X-Envoy-Upstream-Service-Time: - - "136" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"b297fdc1-2a64-481d-9f8b-03207b306c06","name":"rails-runner-8931","description":"rails-runner-8931","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-runner-8931.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"51b2ee83-ff48-4a62-b20f-17300b2423b6","name":"rails-runner-1273","description":"rails-runner-1273","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-runner-1273.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/-oVQ34pGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:14 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/skips_delete_confirmation.yml b/spec/cassettes/Command_RunCleanup/skips_delete_confirmation.yml deleted file mode 100644 index ea494c70..00000000 --- a/spec/cassettes/Command_RunCleanup/skips_delete_confirmation.yml +++ /dev/null @@ -1,243 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - d88f44f7-da5d-4dae-91ea-bd36a727c309 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "7052" - Date: - - Mon, 15 May 2023 23:03:19 GMT - X-Envoy-Upstream-Service-Time: - - "32" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"5f8a0b42-82c7-45b2-b14d-d5b3733b41a0","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"8842d7a0-42a3-4e3d-b4ce-04d54afee3bb","name":"rails-run-4137","description":"rails-run-4137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-4137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-4137-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"a34d8cce-7f9b-4c0d-a144-58fbe29bb2f9","name":"rails-run-5192","description":"rails-run-5192","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-5192/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-5192.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-5192-hd66p547bcrpy.cpln.app"}},{"kind":"workload","id":"c9df16b7-06c6-427c-8e81-bbde933d5926","name":"rails-run-7025","description":"rails-run-7025","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"]);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:1","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app","parentId":"407d11e7-9cdd-4d08-ab5a-fb8c18322645","internalName":"rails-run-7025.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-7025-hd66p547bcrpy.cpln.app"}}],"links":[{"rel":"self","href":"/q/pCx_mUpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcHJhZmFlbC1zaGFrYWNvZGVlZmV0Y2hlaXRlbXM"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Mon, 15 May 2023 23:03:20 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-run-4137 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - da2ce333-6100-4999-9afa-d371a7593f7f - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Mon, 15 May 2023 23:40:09 GMT - X-Envoy-Upstream-Service-Time: - - "62" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Mon, 15 May 2023 23:40:10 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-run-7025 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 5343b8c7-50a9-428c-9c30-c1543605ec95 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Mon, 15 May 2023 23:40:10 GMT - X-Envoy-Upstream-Service-Time: - - "25" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Mon, 15 May 2023 23:40:11 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - 181c36bd-09d5-4d55-bb55-4b917403c39b - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "8255" - Date: - - Wed, 05 Jul 2023 21:43:46 GMT - X-Envoy-Upstream-Service-Time: - - "9" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"51d03e38-ac45-428f-ba61-920951dc14e8","name":"rails-run-0","description":"rails-run-0","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T16:00:00.000Z"},"created":"2023-05-15T16:00:00.000Z","lastModified":"2023-05-15T16:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-run-0/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-run-0.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-run-0-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"9dad9cdc-695e-435d-83e0-2baf8b60bee8","name":"rails-runner-4985","description":"rails-runner-4985","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-4985.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-4985-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"5fdf6390-ddfb-471f-a837-9260a531d885","name":"rails-runner-5137","description":"rails-runner-5137","version":1,"tags":{"cpln/deployTimestamp":"2023-05-15T08:00:00.000Z"},"created":"2023-05-15T08:00:00.000Z","lastModified":"2023-05-15T08:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-5137/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-5137.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-5137-rv167kn7hwk8a.cpln.app"}},{"kind":"workload","id":"da472b95-97e5-4060-ab33-1b09d973f9e2","name":"rails-runner-6669","description":"rails-runner-6669","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-staging"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-staging:2","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app","parentId":"391044b7-708c-4c44-871c-9e904080da78","internalName":"rails-runner-6669.my-app-staging.cpln.local","canonicalEndpoint":"https://rails-runner-6669-rv167kn7hwk8a.cpln.app"}}],"links":[{"rel":"self","href":"/q/DksqTmpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhPWV2YWx1ZWx0dXRvcmlhbC1hcHCjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"=","value":"my-app-staging"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Wed, 05 Jul 2023 21:43:47 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-4985 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 8d077e40-3ac3-450d-8714-6c91d3156725 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Wed, 05 Jul 2023 22:05:52 GMT - X-Envoy-Upstream-Service-Time: - - "33" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Wed, 05 Jul 2023 22:05:53 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-staging/workload/rails-runner-6669 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - ef97b02b-56bf-4a2d-b585-bbf6fc432da5 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Wed, 05 Jul 2023 22:05:53 GMT - X-Envoy-Upstream-Service-Time: - - "61" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Wed, 05 Jul 2023 22:05:54 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/cassettes/Command_RunCleanup/skips_delete_confirmation_for_all_apps_that_start_with_name.yml b/spec/cassettes/Command_RunCleanup/skips_delete_confirmation_for_all_apps_that_start_with_name.yml deleted file mode 100644 index 7605e99c..00000000 --- a/spec/cassettes/Command_RunCleanup/skips_delete_confirmation_for_all_apps_that_start_with_name.yml +++ /dev/null @@ -1,243 +0,0 @@ ---- -http_interactions: - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - cf712142-8ed6-4ea2-a2ef-5061a501dc0d - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "3825" - Date: - - Thu, 06 Jul 2023 00:26:12 GMT - X-Envoy-Upstream-Service-Time: - - "1124" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"1e05759b-bab5-4dfb-bd53-912f4144dc09","name":"rails-run-1527","description":"rails-run-1527","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-run-1527.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-run-1527-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"bc52342e-de2f-45b4-8a52-20945d5881b5","name":"rails-run-9213","description":"rails-run-9213","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"type":"standard","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"unset CONTROLPLANE_RUNNER\nbash"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-e","require \"socket\";s=TCPServer.new(ENV[\"PORT\"] || 80);loop do c=s.accept;c.puts(\"HTTP/1.1 200 OK\\nContent-Length: 2\\n\\nOk\");c.close end"],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","ports":[{"number":3000,"protocol":"http"}],"memory":"512Mi","command":"ruby","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"metric":"cpu","target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-run-9213.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-run-9213-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/Om_bGPpGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWUtcnVuLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-run-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:13 GMT - - request: - method: post - uri: https://api.cpln.io/org/my-org-staging/workload/-query - body: - encoding: UTF-8 - string: '{"kind":"string","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]}}' - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 200 - message: OK - headers: - X-Request-Id: - - c2037b36-e1bc-4c7b-a79b-663c0f02af75 - Content-Type: - - application/json; charset=utf-8 - Content-Length: - - "4428" - Date: - - Thu, 06 Jul 2023 00:26:13 GMT - X-Envoy-Upstream-Service-Time: - - "136" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: '{"kind":"queryresult","items":[{"kind":"workload","id":"b297fdc1-2a64-481d-9f8b-03207b306c06","name":"rails-runner-8931","description":"rails-runner-8931","version":1,"tags":{"cpln/deployTimestamp":"2023-05-10T12:00:00.000Z"},"created":"2023-05-10T12:00:00.000Z","lastModified":"2023-05-10T12:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-1"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-1:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app","parentId":"4893d1c1-56ff-48ef-b75f-609457c3f159","internalName":"rails-runner-8931.my-app-review-1.cpln.local","canonicalEndpoint":"https://rails-runner-8931-sa7yncsq0rysp.cpln.app"}},{"kind":"workload","id":"51b2ee83-ff48-4a62-b20f-17300b2423b6","name":"rails-runner-1273","description":"rails-runner-1273","version":1,"tags":{"cpln/deployTimestamp":"2023-05-13T00:00:00.000Z"},"created":"2023-05-13T00:00:00.000Z","lastModified":"2023-05-13T00:00:00.000Z","links":[{"rel":"self","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273"},{"rel":"org","href":"/org/my-org-staging"},{"rel":"deployment","href":"/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273/deployment"},{"rel":"gvc","href":"/org/my-org-staging/gvc/my-app-review-2"}],"spec":{"job":{"schedule":"* * * * *","historyLimit":5,"restartPolicy":"Never","concurrencyPolicy":"Forbid"},"type":"cron","containers":[{"cpu":"300m","env":[{"name":"CONTROLPLANE_RUNNER","value":"echo ''-- STARTED RUNNER SCRIPT --''\nunset CONTROLPLANE_RUNNER\nif ! eval \"echo TEST\"; then echo \"----- CRASHED -----\"; fi\n\necho \"-- FINISHED RUNNER SCRIPT, DELETING WORKLOAD --\"\nsleep 10 # grace time for logs propagation\ncurl ${CPLN_ENDPOINT}${CPLN_WORKLOAD} -H \"Authorization: ${CONTROLPLANE_TOKEN}\" -X DELETE -s -o /dev/null\nwhile true; do sleep 1; done # wait for SIGTERM\n"},{"name":"LOG_LEVEL","value":"debug"}],"args":["-c","eval \"$CONTROLPLANE_RUNNER\""],"name":"rails","image":"/org/my-org-staging/image/my-app-review-2:NO_IMAGE_AVAILABLE","memory":"512Mi","command":"bash","inheritEnv":true}],"defaultOptions":{"debug":false,"suspend":false,"capacityAI":false,"autoscaling":{"target":95,"maxScale":1,"minScale":1,"maxConcurrency":0,"scaleToZeroDelay":300},"timeoutSeconds":5},"firewallConfig":{"external":{"inboundAllowCIDR":["0.0.0.0/0"],"outboundAllowCIDR":["0.0.0.0/0"],"outboundAllowHostname":[]}},"supportDynamicTags":false},"status":{"endpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app","parentId":"9043c87e-124c-4cf8-aeb0-5575417801af","internalName":"rails-runner-1273.my-app-review-2.cpln.local","canonicalEndpoint":"https://rails-runner-1273-60t0vqtj2mhvt.cpln.app"}}],"links":[{"rel":"self","href":"/q/-oVQ34pGRraW5kaHdvcmtsb2FkZHNwZWOiZW1hdGNoY2FsbGV0ZXJtc4KjY3JlbGNndmNib3BhfmV2YWx1ZW90dXRvcmlhbC1hcHAtcWGjaHByb3BlcnR5ZG5hbWVib3BhfmV2YWx1ZWgtcnVubmVyLWdjb250ZXh0oWdyZXF1ZXN0oWdvcmdOYW1lcXNoYWthY29kZS1zdGFnaW5nZWZldGNoZWl0ZW1z"}],"query":{"kind":"workload","spec":{"match":"all","terms":[{"rel":"gvc","op":"~","value":"my-app-review"},{"property":"name","op":"~","value":"-runner-"}]},"fetch":"items"}}' - recorded_at: Thu, 06 Jul 2023 00:26:14 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-1/workload/rails-run-1527 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 6efd3bae-8c98-4e03-8ad3-d03d22c96f9e - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:18 GMT - X-Envoy-Upstream-Service-Time: - - "46" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:19 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-2/workload/rails-run-9213 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 2e11892e-e4f0-4079-98e9-073755be223d - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:19 GMT - X-Envoy-Upstream-Service-Time: - - "38" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:20 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-1/workload/rails-runner-8931 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - cb4e3876-d98d-4817-af0a-84351c38901f - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:20 GMT - X-Envoy-Upstream-Service-Time: - - "26" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:21 GMT - - request: - method: delete - uri: https://api.cpln.io/org/my-org-staging/gvc/my-app-review-2/workload/rails-runner-1273 - body: - encoding: US-ASCII - string: "" - headers: - Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 - Accept: - - "*/*" - User-Agent: - - Ruby - Host: - - api.cpln.io - Content-Type: - - application/json - Authorization: - - "" - response: - status: - code: 202 - message: Accepted - headers: - X-Request-Id: - - 85d5184c-48a1-401d-99ec-5849b7426687 - Content-Type: - - text/plain; charset=utf-8 - Content-Length: - - "8" - Date: - - Thu, 06 Jul 2023 00:48:21 GMT - X-Envoy-Upstream-Service-Time: - - "27" - Server: - - istio-envoy - body: - encoding: UTF-8 - string: Accepted - recorded_at: Thu, 06 Jul 2023 00:48:22 GMT -recorded_with: VCR 6.1.0 diff --git a/spec/command/apply_template_spec.rb b/spec/command/apply_template_spec.rb new file mode 100644 index 00000000..3f137361 --- /dev/null +++ b/spec/command/apply_template_spec.rb @@ -0,0 +1,173 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::ApplyTemplate do + context "when any template does not exist" do + let!(:app) { dummy_test_app } + + it "raises error" do + result = run_cpl_command("apply-template", "gvc", "rails", "nonexistent", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Missing templates") + expect(result[:stderr]).to include("- nonexistent") + end + end + + context "when all templates exist" do + let!(:app) { dummy_test_app } + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "applies valid templates" do + result = run_cpl_command("apply-template", "gvc", "rails", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [app] #{app}") + expect(result[:stderr]).to include("- [identity] #{app}-identity") + expect(result[:stderr]).to include("- [workload] rails") + end + + it "fails to apply invalid templates" do + result = run_cpl_command("apply-template", "invalid", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Failed to apply templates") + expect(result[:stderr]).to include("- invalid") + end + + it "applies valid templates and fails to apply invalid templates" do + result = run_cpl_command("apply-template", "gvc", "invalid", "rails", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [app] #{app}") + expect(result[:stderr]).to include("- [identity] #{app}-identity") + expect(result[:stderr]).to include("- [workload] rails") + expect(result[:stderr]).to include("Failed to apply templates") + expect(result[:stderr]).to include("- invalid") + end + + it "replaces all variables correctly" do + apply_result = run_cpl_command("apply-template", "gvc-with-all-variables", "-a", app) + env_result = run_cpl_command("env", "-a", app) + + org = dummy_test_org + location = "aws-us-east-2" + image = "#{app}:NO_IMAGE_AVAILABLE" + identity = "#{app}-identity" + prefix = dummy_test_app_prefix + expect(apply_result[:status]).to eq(0) + expect(env_result[:status]).to eq(0) + expect(apply_result[:stderr]).not_to include("DEPRECATED") + expect(env_result[:stdout]).to include("ORG=#{org}") + expect(env_result[:stdout]).to include("NAME=#{app}") + expect(env_result[:stdout]).to include("LOCATION=#{location}") + expect(env_result[:stdout]).to include("LOCATION_LINK=/org/#{org}/location/#{location}") + expect(env_result[:stdout]).to include("IMAGE=#{image}") + expect(env_result[:stdout]).to include("IMAGE_LINK=/org/#{org}/image/#{image}") + expect(env_result[:stdout]).to include("IDENTITY=#{identity}") + expect(env_result[:stdout]).to include("IDENTITY_LINK=/org/#{org}/gvc/#{app}/identity/#{identity}") + expect(env_result[:stdout]).to include("SECRETS=#{prefix}-secrets") + expect(env_result[:stdout]).to include("SECRETS_POLICY=#{prefix}-secrets-policy") + end + + it "replaces deprecated variables correctly and warns about them" do + apply_result = run_cpl_command("apply-template", "gvc-with-deprecated-variables", "-a", app) + env_result = run_cpl_command("env", "-a", app) + + org = dummy_test_org + location = "aws-us-east-2" + image = "#{app}:NO_IMAGE_AVAILABLE" + expect(apply_result[:status]).to eq(0) + expect(env_result[:status]).to eq(0) + expect(apply_result[:stderr]).to include("DEPRECATED") + expect(apply_result[:stderr]).to include("APP_ORG -> {{APP_ORG}}") + expect(apply_result[:stderr]).to include("APP_GVC -> {{APP_NAME}}") + expect(apply_result[:stderr]).to include("APP_LOCATION -> {{APP_LOCATION}}") + expect(apply_result[:stderr]).to include("APP_IMAGE -> {{APP_IMAGE}}") + expect(env_result[:stdout]).to include("ORG=#{org}") + expect(env_result[:stdout]).to include("NAME=#{app}") + expect(env_result[:stdout]).to include("LOCATION=#{location}") + expect(env_result[:stdout]).to include("IMAGE=#{image}") + end + end + + context "when app already exists" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "asks for confirmation and does nothing" do + allow(Shell).to receive(:confirm).with(include("App '#{app}' already exists")).and_return(false) + + result = run_cpl_command("apply-template", "gvc", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Skipped templates") + expect(result[:stderr]).to include("- gvc") + end + + it "asks for confirmation and re-creates app" do + allow(Shell).to receive(:confirm).with(include("App '#{app}' already exists")).and_return(true) + + result = run_cpl_command("apply-template", "gvc", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [app] #{app}") + end + + it "skips confirmation and re-creates app" do + allow(Shell).to receive(:confirm).and_return(false) + + result = run_cpl_command("apply-template", "gvc", "-a", app, "--yes") + + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [app] #{app}") + end + end + + context "when workload already exists" do + let!(:app) { dummy_test_app("with-rails", create_if_not_exists: true) } + + it "asks for confirmation and does nothing" do + allow(Shell).to receive(:confirm).with(include("Workload 'rails' already exists")).and_return(false) + + result = run_cpl_command("apply-template", "rails", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Skipped templates") + expect(result[:stderr]).to include("- rails") + end + + it "asks for confirmation and re-creates workload" do + allow(Shell).to receive(:confirm).with(include("Workload 'rails' already exists")).and_return(true) + + result = run_cpl_command("apply-template", "rails", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [workload] rails") + end + + it "skips confirmation and re-creates workload" do + allow(Shell).to receive(:confirm).and_return(false) + + result = run_cpl_command("apply-template", "rails", "-a", app, "--yes") + + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("- [workload] rails") + end + end +end diff --git a/spec/command/build_image_spec.rb b/spec/command/build_image_spec.rb new file mode 100644 index 00000000..fded24b3 --- /dev/null +++ b/spec/command/build_image_spec.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::BuildImage do + context "when Docker is not running" do + let!(:app) { dummy_test_app } + + before do + allow(Shell).to receive(:cmd).with("docker", "version", anything).and_return({ success: false }) + end + + it "raises error" do + result = run_cpl_command("build-image", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't run Docker") + end + end + + context "when Dockerfile does not exist" do + let!(:app) { dummy_test_app("with-nonexistent-dockerfile") } + + it "raises error" do + result = run_cpl_command("build-image", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find Dockerfile") + end + end + + context "when Dockerfile is invalid" do + let!(:app) { dummy_test_app("with-invalid-dockerfile") } + + it "fails to build and push image" do + result = run_cpl_command("build-image", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).not_to include("Pushed image") + end + end + + context "when Dockerfile is valid" do + let!(:app) { dummy_test_app } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "builds and pushes images", :slow do + result1 = run_cpl_command("build-image", "-a", app) + # Subsequent build increases number + result2 = run_cpl_command("build-image", "-a", app) + # Adds commit hash + result3 = run_cpl_command("build-image", "-a", app, "--commit", "abc123") + + expect(result1[:status]).to eq(0) + expect(result2[:status]).to eq(0) + expect(result3[:status]).to eq(0) + expect(result1[:stderr]).to match(%r{Pushed image to '/org/.+?/image/#{app}:1'}) + expect(result2[:stderr]).to match(%r{Pushed image to '/org/.+?/image/#{app}:2'}) + expect(result3[:stderr]).to match(%r{Pushed image to '/org/.+?/image/#{app}:3_abc123'}) + end + + it "passes additional options to `docker build`", :slow do + allow(Kernel).to receive(:system).with(match(/docker build.+?TEST=123/)).and_call_original + allow(Kernel).to receive(:system).with(include("docker push")).and_call_original + + result = run_cpl_command("build-image", "-a", app, "--build-arg", "TEST=123") + + expect(Kernel).to have_received(:system).twice + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(%r{Pushed image to '/org/.+?/image/#{app}:1'}) + end + end +end diff --git a/spec/command/cleanup_images_spec.rb b/spec/command/cleanup_images_spec.rb index 0a0a3b57..4f1f85f4 100644 --- a/spec/command/cleanup_images_spec.rb +++ b/spec/command/cleanup_images_spec.rb @@ -3,164 +3,191 @@ require "spec_helper" describe Command::CleanupImages do - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") # rubocop:disable RSpec/AnyInstance - - Timecop.freeze(Time.local(2023, 8, 23)) + context "when 'image_retention_max_qty' or 'image_retention_days' are not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("cleanup-images", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find either option 'image_retention_max_qty' or 'image_retention_days'") + end end - it "displays error if 'image_retention_max_qty' and 'image_retention_days' are not set" do - allow(Shell).to receive(:abort).with("Can't find either option 'image_retention_max_qty' " \ - "or 'image_retention_days' for app 'my-app-test-1' in 'controlplane.yml'.") + context "when there are no images to delete" do + let!(:app) { dummy_test_app } - args = ["-a", "my-app-test-1"] - Cpl::Cli.start([described_class::NAME, *args]) + it "displays message" do + result = run_cpl_command("cleanup-images", "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No images to delete") + end end - it "displays empty message", vcr: true do - expected_output = <<~OUTPUT - No images to delete. - OUTPUT + context "when app does not exist" do + let!(:app) { dummy_test_app } - output = command_output do - args = ["-a", "my-app-test-2"] - Cpl::Cli.start([described_class::NAME, *args]) + before do + run_cpl_command!("build-image", "-a", app) # app:1 end - expect(output).to eq(expected_output) + it "deletes leftover images", :slow do + allow(Shell).to receive(:confirm).with(include("1 images")).and_return(true) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting image '#{app}:1'[.]+? done!/) + end end - it "lists images to delete based on max quantity and days", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 6 images?") - .and_return(false) + context "when app exists" do + let!(:app) { dummy_test_app } - expected_output = <<~OUTPUT - Images to delete: - - my-app-test-3:508_149ba15 (#{Shell.color('2023-08-02T08:35:20+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:509_1ddaddb (#{Shell.color('2023-08-03T08:50:12+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:510_ad671e6 (#{Shell.color('2023-08-04T01:17:29+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:511_7ef99dd (#{Shell.color('2023-08-05T02:51:14+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:512_346384f (#{Shell.color('2023-08-06T03:08:27+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:513_ec7930a (#{Shell.color('2023-08-07T13:20:18+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - OUTPUT + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + run_cpl_command!("build-image", "-a", app) # app:1 + run_cpl_command!("build-image", "-a", app) # app:2 + end - output = command_output do - args = ["-a", "my-app-test-3"] - Cpl::Cli.start([described_class::NAME, *args]) + after do + run_cpl_command!("delete", "-a", app, "--yes") end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) - end + it "asks for confirmation and does nothing", :slow do + allow(Shell).to receive(:confirm).with(include("1 images")).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).not_to include("Deleting image") + end - it "lists images to delete based on max quantity", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 6 images?") - .and_return(false) + it "asks for confirmation and deletes images", :slow do + allow(Shell).to receive(:confirm).with(include("1 images")).and_return(true) - expected_output = <<~OUTPUT - Images to delete: - - my-app-test-4:508_149ba15 (#{Shell.color('2023-08-02T08:35:20+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - - my-app-test-4:509_1ddaddb (#{Shell.color('2023-08-03T08:50:12+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - - my-app-test-4:510_ad671e6 (#{Shell.color('2023-08-04T01:17:29+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - - my-app-test-4:511_7ef99dd (#{Shell.color('2023-08-05T02:51:14+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - - my-app-test-4:512_346384f (#{Shell.color('2023-08-06T03:08:27+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - - my-app-test-4:513_ec7930a (#{Shell.color('2023-08-07T13:20:18+00:00', :red)} - #{Shell.color('exceeds max quantity of 12', :red)}) - OUTPUT + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app) + travel_back - output = command_output do - args = ["-a", "my-app-test-4"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting image '#{app}:1'[.]+? done!/) end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) + it "skips confirmation and deletes images", :slow do + allow(Shell).to receive(:confirm).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app, "--yes") + travel_back + + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting image '#{app}:1'[.]+? done!/) + end end - it "lists images to delete based on days", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 6 images?") - .and_return(false) + context "with single app based on max quantity" do + let!(:app) { dummy_test_app("with-image-retention-max-qty") } - expected_output = <<~OUTPUT - Images to delete: - - my-app-test-5:508_149ba15 (#{Shell.color('2023-08-02T08:35:20+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - - my-app-test-5:509_1ddaddb (#{Shell.color('2023-08-03T08:50:12+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - - my-app-test-5:510_ad671e6 (#{Shell.color('2023-08-04T01:17:29+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - - my-app-test-5:511_7ef99dd (#{Shell.color('2023-08-05T02:51:14+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - - my-app-test-5:512_346384f (#{Shell.color('2023-08-06T03:08:27+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - - my-app-test-5:513_ec7930a (#{Shell.color('2023-08-07T13:20:18+00:00', :red)} - #{Shell.color('older than 12 days', :red)}) - OUTPUT + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + end - output = command_output do - args = ["-a", "my-app-test-5"] - Cpl::Cli.start([described_class::NAME, *args]) + after do + run_cpl_command!("delete", "-a", app, "--yes") end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) + it "lists correct images", :slow do + allow(Shell).to receive(:confirm).with(include("2 images")).and_return(false) + + # Excess images, will be listed + run_cpl_command!("build-image", "-a", app) # app:1 + run_cpl_command!("build-image", "-a", app) # app:2 + # Images that don't exceed max quantity of 3, won't be listed + run_cpl_command!("build-image", "-a", app) # app:3 + run_cpl_command!("build-image", "-a", app) # app:4 + run_cpl_command!("build-image", "-a", app) # app:5 + # Latest image, excluded from max quantity calculation, won't be listed + run_cpl_command!("build-image", "-a", app) # app:6 + result = run_cpl_command("cleanup-images", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app}:1 \(.+? - exceeds max quantity of 3\)/) + expect(result[:stderr]).to match(/- #{app}:2 \(.+? - exceeds max quantity of 3\)/) + end end - it "deletes images", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 6 images?") - .and_return(true) - - expected_output = <<~OUTPUT - Images to delete: - - my-app-test-3:508_149ba15 (#{Shell.color('2023-08-02T08:35:20+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:509_1ddaddb (#{Shell.color('2023-08-03T08:50:12+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:510_ad671e6 (#{Shell.color('2023-08-04T01:17:29+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:511_7ef99dd (#{Shell.color('2023-08-05T02:51:14+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:512_346384f (#{Shell.color('2023-08-06T03:08:27+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:513_ec7930a (#{Shell.color('2023-08-07T13:20:18+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - Deleting image 'my-app-test-3:508_149ba15'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:509_1ddaddb'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:510_ad671e6'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:511_7ef99dd'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:512_346384f'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:513_ec7930a'... #{Shell.color('done!', :green)} - OUTPUT - - output = command_output do - args = ["-a", "my-app-test-3"] - Cpl::Cli.start([described_class::NAME, *args]) - end - - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) + context "with single app based on days" do + let!(:app) { dummy_test_app("with-image-retention-days") } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "lists correct images", :slow do + allow(Shell).to receive(:confirm).with(include("2 images")).and_return(false) + + # Old images, will be listed + run_cpl_command!("build-image", "-a", app) # app:1 + run_cpl_command!("build-image", "-a", app) # app:2 + # Latest image, excluded from days calculation, won't be listed + run_cpl_command!("build-image", "-a", app) # app:3 + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app}:1 \(.+? - older than 30 days\)/) + expect(result[:stderr]).to match(/- #{app}:2 \(.+? - older than 30 days\)/) + end end - it "skips delete confirmation", vcr: true do - allow(Shell).to receive(:confirm) - - expected_output = <<~OUTPUT - Images to delete: - - my-app-test-3:508_149ba15 (#{Shell.color('2023-08-02T08:35:20+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:509_1ddaddb (#{Shell.color('2023-08-03T08:50:12+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:510_ad671e6 (#{Shell.color('2023-08-04T01:17:29+00:00', :red)} - #{Shell.color('exceeds max quantity of 15', :red)}) - - my-app-test-3:511_7ef99dd (#{Shell.color('2023-08-05T02:51:14+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:512_346384f (#{Shell.color('2023-08-06T03:08:27+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - my-app-test-3:513_ec7930a (#{Shell.color('2023-08-07T13:20:18+00:00', :red)} - #{Shell.color('older than 15 days', :red)}) - - Deleting image 'my-app-test-3:508_149ba15'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:509_1ddaddb'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:510_ad671e6'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:511_7ef99dd'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:512_346384f'... #{Shell.color('done!', :green)} - Deleting image 'my-app-test-3:513_ec7930a'... #{Shell.color('done!', :green)} - OUTPUT - - output = command_output do - args = ["-a", "my-app-test-3", "-y"] - Cpl::Cli.start([described_class::NAME, *args]) - end - - expect(Shell).not_to have_received(:confirm) - expect(output).to eq(expected_output) + context "with multiple apps" do + let!(:app_prefix) { dummy_test_app_prefix("with-image-retention") } + let!(:app1) { dummy_test_app("with-image-retention", "1", create_if_not_exists: true) } + let!(:app2) { dummy_test_app("with-image-retention", "2", create_if_not_exists: true) } + + it "lists correct images from exact app", :slow do + allow(Shell).to receive(:confirm).with(include("2 images")).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app1) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app1}:1 \(.+? - older than 30 days\)/) + expect(result[:stderr]).to match(/- #{app1}:2 \(.+? - older than 30 days\)/) + end + + it "lists correct images from all matching apps", :slow do + allow(Shell).to receive(:confirm).with(include("4 images")).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-images", "-a", app_prefix) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app1}:1 \(.+? - older than 30 days\)/) + expect(result[:stderr]).to match(/- #{app1}:2 \(.+? - older than 30 days\)/) + expect(result[:stderr]).to match(/- #{app2}:1 \(.+? - older than 30 days\)/) + expect(result[:stderr]).to match(/- #{app2}:2 \(.+? - older than 30 days\)/) + end end end diff --git a/spec/command/cleanup_stale_apps_spec.rb b/spec/command/cleanup_stale_apps_spec.rb new file mode 100644 index 00000000..5972453a --- /dev/null +++ b/spec/command/cleanup_stale_apps_spec.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::CleanupStaleApps do + let!(:app_prefix) { dummy_test_app_prefix("with-stale-app-image-deployed-days") } + + context "when 'stale_app_image_deployed_days' is not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("cleanup-stale-apps", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'stale_app_image_deployed_days'") + end + end + + context "when there are no stale apps to delete" do + let!(:app) { dummy_test_app } + + it "displays message" do + result = run_cpl_command("cleanup-stale-apps", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No stale apps found") + end + end + + context "when there are stale apps to delete" do + let!(:app1) { dummy_test_app("with-stale-app-image-deployed-days") } + let!(:app2) { dummy_test_app("with-stale-app-image-deployed-days") } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app1) + run_cpl_command!("apply-template", "gvc", "-a", app2) + run_cpl_command!("build-image", "-a", app1) + run_cpl_command!("build-image", "-a", app2) + end + + after do + run_cpl_command!("delete", "-a", app1, "--yes") + run_cpl_command!("delete", "-a", app2, "--yes") + end + + it "asks for confirmation and does nothing", :slow do + allow(Shell).to receive(:confirm).with(include("2 apps")).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-stale-apps", "-a", app_prefix) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).not_to include("Deleting app") + end + + it "asks for confirmation and deletes stale apps", :slow do + allow(Shell).to receive(:confirm).with(include("2 apps")).and_return(true) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-stale-apps", "-a", app_prefix) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting app '#{app1}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting image '#{app1}:1'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting app '#{app2}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting image '#{app2}:1'[.]+? done!/) + end + + it "skips confirmation and deletes stale apps", :slow do + allow(Shell).to receive(:confirm).and_return(false) + + travel_to_days_later(30) + result = run_cpl_command("cleanup-stale-apps", "-a", app_prefix, "--yes") + travel_back + + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting app '#{app1}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting image '#{app1}:1'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting app '#{app2}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting image '#{app2}:1'[.]+? done!/) + end + end + + context "with multiple apps" do + let!(:app1) { dummy_test_app("with-stale-app-image-deployed-days") } + let!(:app2) { dummy_test_app("with-stale-app-image-deployed-days") } + let!(:app3) { dummy_test_app("with-stale-app-image-deployed-days") } + let!(:app4) { dummy_test_app("with-stale-app-image-deployed-days") } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app1) + run_cpl_command!("apply-template", "gvc", "-a", app2) + run_cpl_command!("apply-template", "gvc", "-a", app3) + run_cpl_command!("apply-template", "gvc", "-a", app4) + end + + after do + run_cpl_command!("delete", "-a", app1, "--yes") + run_cpl_command!("delete", "-a", app2, "--yes") + run_cpl_command!("delete", "-a", app3, "--yes") + run_cpl_command!("delete", "-a", app4, "--yes") + end + + it "lists correct stale apps", :slow do + allow(Shell).to receive(:confirm).with(include("2 apps")).and_return(false) + + # We need to stub the image from app3 to have the current date, + # as Control Plane does not allow manipulating the creation date of an image + allow_any_instance_of(Controlplane).to receive(:query_images).and_wrap_original do |original, *args, &block| # rubocop:disable RSpec/AnyInstance + original_return = original.call(*args, &block) + original_return["items"].each do |item| + item["created"] = Time.now.to_s if item["name"].start_with?("#{app3}:") + end + original_return + end + + # Apps with old image, will be listed + run_cpl_command!("build-image", "-a", app1) + run_cpl_command!("build-image", "-a", app2) + travel_to_days_later(30) + # App with new image, wont't be listed + run_cpl_command!("build-image", "-a", app3) + result = run_cpl_command("cleanup-stale-apps", "-a", app_prefix) + travel_back + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("- #{app1}") + expect(result[:stderr]).to include("- #{app2}") + expect(result[:stderr]).not_to include("- #{app3}") + expect(result[:stderr]).not_to include("- #{app4}") + end + end +end diff --git a/spec/command/config_spec.rb b/spec/command/config_spec.rb new file mode 100644 index 00000000..e900b3c9 --- /dev/null +++ b/spec/command/config_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Config do + context "when no app is provided" do + it "displays config for each app" do + result = run_cpl_command("config") + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("Config for app 'dummy-test'") + expect(result[:stdout]).to include("Config for app 'dummy-test-with-nothing'") + expect(result[:stdout]).to match(/^ match_if_app_name_starts_with: true$/) + expect(result[:stdout]).to match(/^ - rails$/) + end + end + + context "when app is provided" do + let!(:app) { dummy_test_app } + + it "displays config for specific app" do + result = run_cpl_command("config", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("Current config (app '#{app}')") + expect(result[:stdout]).to match(/^ match_if_app_name_starts_with: true$/) + expect(result[:stdout]).to match(/^ - rails$/) + end + end +end diff --git a/spec/command/copy_image_from_upstream_spec.rb b/spec/command/copy_image_from_upstream_spec.rb index 9ce39fb6..07276601 100644 --- a/spec/command/copy_image_from_upstream_spec.rb +++ b/spec/command/copy_image_from_upstream_spec.rb @@ -3,70 +3,135 @@ require "spec_helper" describe Command::CopyImageFromUpstream do - # rubocop:disable RSpec/AnyInstance - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_ORG_UPSTREAM", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_UPSTREAM", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") - allow_any_instance_of(described_class).to receive(:ensure_docker_running!) - allow_any_instance_of(Controlplane).to receive(:profile_exists?).and_return(false) - allow_any_instance_of(Controlplane).to receive(:profile_create).and_return(true) - allow_any_instance_of(Controlplane).to receive(:profile_switch).and_return(true) - allow_any_instance_of(Controlplane).to receive(:profile_delete).and_return(true) - allow_any_instance_of(Controlplane).to receive(:image_login).and_return(true) - allow_any_instance_of(Controlplane).to receive(:image_pull).and_return(true) - allow_any_instance_of(Controlplane).to receive(:image_tag).and_return(true) - allow_any_instance_of(Controlplane).to receive(:image_push).and_return(true) + context "when Docker is not running" do + let!(:app) { dummy_test_app } + + before do + allow(Shell).to receive(:cmd).with("docker", "version", anything).and_return({ success: false }) + end + + it "raises error" do + result = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", "token") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't run Docker") + end end - it "copies commit from upstream if exists", vcr: true do - allow_any_instance_of(Command::Base).to receive(:latest_image) - .with("my-app-staging", "my-org-staging").and_return("my-app-staging:0_123abc") - allow_any_instance_of(Command::Base).to receive(:latest_image) - .with("my-app-production", "my-org-production").and_return("my-app-production:8_456def") - - expected_output = <<~OUTPUT - Creating upstream profile... #{Shell.color('done!', :green)} - Fetching upstream image URL... #{Shell.color('done!', :green)} - Fetching app image URL... #{Shell.color('done!', :green)} - Pulling image from 'my-org-staging.registry.cpln.io/my-app-staging:0_123abc'... #{Shell.color('done!', :green)} - Pushing image to 'my-org-production.registry.cpln.io/my-app-production:9_123abc'... #{Shell.color('done!', :green)} - Deleting upstream profile... #{Shell.color('done!', :green)} - OUTPUT - - output = command_output do - args = ["-a", "my-app-production", "--upstream-token", "upstream_token"] - Cpl::Cli.start([described_class::NAME, *args]) + context "when 'upstream' is not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", "token") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'upstream'") end + end + + context "when upstream app is not defined" do + let!(:app) { dummy_test_app("with-undefined-upstream") } - expect(output).to eq(expected_output) + it "raises error" do + result = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", "token") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'cpln_org' for app 'undefined'") + end end - it "does not copy commit from upstream if not exists", vcr: true do - allow_any_instance_of(Command::Base).to receive(:latest_image) - .with("my-app-staging", "my-org-staging").and_return("my-app-staging:0") - allow_any_instance_of(Command::Base).to receive(:latest_image) - .with("my-app-production", "my-org-production").and_return("my-app-production:8_456def") - - expected_output = <<~OUTPUT - Creating upstream profile... #{Shell.color('done!', :green)} - Fetching upstream image URL... #{Shell.color('done!', :green)} - Fetching app image URL... #{Shell.color('done!', :green)} - Pulling image from 'my-org-staging.registry.cpln.io/my-app-staging:0'... #{Shell.color('done!', :green)} - Pushing image to 'my-org-production.registry.cpln.io/my-app-production:9'... #{Shell.color('done!', :green)} - Deleting upstream profile... #{Shell.color('done!', :green)} - OUTPUT - - output = command_output do - args = ["-a", "my-app-production", "--upstream-token", "upstream_token"] - Cpl::Cli.start([described_class::NAME, *args]) + context "when 'cpln_org' is not defined for upstream app" do + let!(:upstream_app) { dummy_test_app("without-org") } + let!(:app) { dummy_test_app } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app end - expect(output).to eq(expected_output) + it "raises error" do + result = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", "token") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'cpln_org' for app '#{upstream_app}'") + end + end + + context "when using invalid token for upstream org" do + let!(:upstream_app) { dummy_test_app } + let!(:app) { dummy_test_app } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app + # Ideally, we should have a different org, but for testing purposes, this works + ENV["CPLN_ORG_UPSTREAM"] = dummy_test_org + + run_cpl_command!("apply-template", "gvc", "-a", upstream_app) + run_cpl_command!("apply-template", "gvc", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", upstream_app, "--yes") + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "fails to fetch upstream image URL", :slow do + run_cpl_command!("build-image", "-a", upstream_app) + result = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", "token") + + expect(ENV.fetch("CPLN_PROFILE", nil)).to eq("default") + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to match(/Creating upstream profile[.]+? done!/) + expect(result[:stderr]).to match(/Fetching upstream image URL[.]+? failed!/) + expect(result[:stderr]).to match(/Deleting upstream profile[.]+? done!/) + end + end + + context "when using valid token for upstream org" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:upstream_app) { dummy_test_app } + let!(:app) { dummy_test_app } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app + # Ideally, we should have a different org, but for testing purposes, this works + ENV["CPLN_ORG_UPSTREAM"] = dummy_test_org + + run_cpl_command!("apply-template", "gvc", "-a", upstream_app) + run_cpl_command!("apply-template", "gvc", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", upstream_app, "--yes") + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "copies images from upstream", :slow do + # Simulates looping through generated profile names to avoid conflicts + allow_any_instance_of(Controlplane).to receive(:profile_exists?).and_return(true, false) # rubocop:disable RSpec/AnyInstance + + run_cpl_command!("build-image", "-a", upstream_app, "--commit", "abc123") + run_cpl_command!("build-image", "-a", upstream_app) + # Copies latest image + result1 = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", token) + # Copies specific image with commit hash + result2 = run_cpl_command("copy-image-from-upstream", "-a", app, "--upstream-token", token, + "--image", "#{upstream_app}:1_abc123") + + expect(ENV.fetch("CPLN_PROFILE", nil)).to eq("default") + expect(result1[:status]).to eq(0) + expect(result2[:status]).to eq(0) + expect(result1[:stderr]).to match(/Creating upstream profile[.]+? done!/) + expect(result1[:stderr]).to match(/Fetching upstream image URL[.]+? done!/) + expect(result1[:stderr]).to match(/Fetching app image URL[.]+? done!/) + expect(result1[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:2'[.]+? done!}) + expect(result1[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'[.]+? done!}) + expect(result1[:stderr]).to match(/Deleting upstream profile[.]+? done!/) + expect(result2[:stderr]).to match(/Creating upstream profile[.]+? done!/) + expect(result2[:stderr]).to match(/Fetching upstream image URL[.]+? done!/) + expect(result2[:stderr]).to match(/Fetching app image URL[.]+? done!/) + expect(result2[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:1_abc123'[.]+? done!}) + expect(result2[:stderr]).to match(%r{Pushing image to '.+?/#{app}:2_abc123'[.]+? done!}) + expect(result2[:stderr]).to match(/Deleting upstream profile[.]+? done!/) + end end - # rubocop:enable RSpec/AnyInstance end diff --git a/spec/command/delete_spec.rb b/spec/command/delete_spec.rb new file mode 100644 index 00000000..4474f140 --- /dev/null +++ b/spec/command/delete_spec.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Delete do + context "when app does not exist" do + let!(:app) { dummy_test_app } + + it "displays message" do + result = run_cpl_command("delete", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("App '#{app}' does not exist") + end + end + + context "when app exists" do + let!(:app) { dummy_test_app } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "asks for confirmation and does nothing" do + allow(Shell).to receive(:confirm).with(include(app)).and_return(false) + + result = run_cpl_command("delete", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No volumesets to delete") + expect(result[:stderr]).to include("No images to delete") + expect(result[:stderr]).not_to include("Deleting app") + end + + it "asks for confirmation and deletes app" do + allow(Shell).to receive(:confirm).with(include(app)).and_return(true) + + result = run_cpl_command("delete", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No volumesets to delete") + expect(result[:stderr]).to include("No images to delete") + expect(result[:stderr]).to match(/Deleting app '#{app}'[.]+? done!/) + end + + it "skips confirmation and deletes app" do + allow(Shell).to receive(:confirm).and_return(false) + + result = run_cpl_command("delete", "-a", app, "--yes") + + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No volumesets to delete") + expect(result[:stderr]).to include("No images to delete") + expect(result[:stderr]).to match(/Deleting app '#{app}'[.]+? done!/) + end + end + + context "when app has volumesets and images" do + let!(:app) { dummy_test_app } + + before do + run_cpl_command!("apply-template", "gvc", "rails", "postgres-with-volume", "detached-volume", "-a", app) + run_cpl_command!("build-image", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "deletes app with volumesets and images", :slow do + allow(Shell).to receive(:confirm).with(include(app)).and_return(true) + + result = run_cpl_command("delete", "-a", app) + + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting volumeset 'detached-volume'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting volumeset 'postgres-volume'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting app '#{app}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting image '#{app}:1'[.]+? done!/) + end + end +end diff --git a/spec/command/deploy_image_spec.rb b/spec/command/deploy_image_spec.rb new file mode 100644 index 00000000..bdd7d99d --- /dev/null +++ b/spec/command/deploy_image_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::DeployImage do + context "when image does not exist" do + let!(:app) { dummy_test_app("with-rails", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("deploy-image", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to match(/Image '#{app}:NO_IMAGE_AVAILABLE' does not exist/) + end + end + + context "when any app workload does not exist" do + let!(:app) { dummy_test_app } + + before do + run_cpl_command!("apply-template", "gvc", "-a", app) + run_cpl_command!("build-image", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "raises error", :slow do + result = run_cpl_command("deploy-image", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when not running release phase" do + let!(:app) { dummy_test_app("with-rails-with-non-app-image", create_if_not_exists: true) } + + it "deploys latest image to app workloads", :slow do + result = run_cpl_command("deploy-image", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).not_to include("Running release script") + expect(result[:stderr]).to match(%r{- rails: https://rails-.+?.cpln.app}) + expect(result[:stderr]).not_to include("- rails-with-non-app-image:") + end + end + + context "when 'release_script' is not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("deploy-image", "-a", app, "--run-release-phase") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'release_script'") + end + end + + context "when release script does not exist" do + let!(:app) { dummy_test_app("with-nonexistent-release-script") } + + it "raises error" do + result = run_cpl_command("deploy-image", "-a", app, "--run-release-phase") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find release script") + end + end + + context "when release script is invalid" do + let!(:app) { dummy_test_app("with-invalid-release-script") } + + before do + ENV["APP_NAME"] = app + + allow(Kernel).to receive(:sleep) + + run_cpl_command!("apply-template", "gvc", "rails", "-a", app) + run_cpl_command!("build-image", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "fails to run release script and fails to deploy image", :slow do + result = run_cpl_command("deploy-image", "-a", app, "--run-release-phase") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Running release script") + expect(result[:stderr]).to include("Failed to run release script") + expect(result[:stderr]).not_to include("- rails:") + end + end + + context "when release script is valid" do + let!(:app) { dummy_test_app("with-rails-with-non-app-image", create_if_not_exists: true) } + + before do + ENV["APP_NAME"] = app + + allow(Kernel).to receive(:sleep) + + run_cpl_command!("ps:start", "-a", app, "--workload", "postgres", "--wait") + end + + it "runs release script and deploys image", :slow do + result = run_cpl_command("deploy-image", "-a", app, "--run-release-phase") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Running release script") + expect(result[:stderr]).not_to include("Failed to run release script") + expect(result[:stderr]).to match(%r{- rails: https://rails-.+?.cpln.app}) + expect(result[:stderr]).not_to include("- rails-with-non-app-image:") + end + end +end diff --git a/spec/command/env_spec.rb b/spec/command/env_spec.rb new file mode 100644 index 00000000..afbcc1d4 --- /dev/null +++ b/spec/command/env_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Env do + context "when app does not exist" do + let!(:app) { dummy_test_app } + + it "raises error" do + result = run_cpl_command("env", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find app '#{app}'") + end + end + + context "when app exists" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "displays app-specific environment variables" do + result = run_cpl_command("env", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]) + .to include("DATABASE_URL=postgres://postgres:password@postgres.#{app}.cpln.local:5432/#{app}") + end + end +end diff --git a/spec/command/exists_spec.rb b/spec/command/exists_spec.rb new file mode 100644 index 00000000..1418e977 --- /dev/null +++ b/spec/command/exists_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Exists do + context "when app does not exist" do + let!(:app) { dummy_test_app } + + it "exits with non-zero status" do + result = run_cpl_command("exists", "-a", app) + + expect(result[:status]).not_to eq(0) + end + end + + context "when app exists" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "exits with zero status" do + result = run_cpl_command("exists", "-a", app) + + expect(result[:status]).to eq(0) + end + end +end diff --git a/spec/command/info_spec.rb b/spec/command/info_spec.rb new file mode 100644 index 00000000..ce2f730d --- /dev/null +++ b/spec/command/info_spec.rb @@ -0,0 +1,259 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Info do + before do + allow_any_instance_of(described_class).to receive(:app_org).and_return(dummy_test_org) # rubocop:disable RSpec/AnyInstance + end + + context "when 'cpln_org' is not defined for app" do + let!(:app_prefix) { dummy_test_app_prefix("info") } + + before do + allow_any_instance_of(described_class).to receive(:app_org).and_call_original # rubocop:disable RSpec/AnyInstance + end + + it "does not include app" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app_prefix) + + expect(Shell).not_to have_received(:color) + .with(include("Any app starting with '#{app_prefix}'"), :red) + expect(result[:status]).to eq(0) + expect(result[:stdout]).not_to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + end + + context "when nothing is missing" do + let!(:app_prefix) { dummy_test_app_prefix("info-with-nothing-missing") } + let!(:app1) { dummy_test_app("info-with-nothing-missing", "1", create_if_not_exists: true) } + let!(:app2) { dummy_test_app("info-with-nothing-missing", "2", create_if_not_exists: true) } + + it "does not highlight anything for single app" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app1) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with("rails", :red) + expect(Shell).not_to have_received(:color).with("postgres", :red) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).not_to include("cpl setup-app") + expect(result[:stdout]).not_to include("cpl apply-template") + end + + it "does not highlight anything for multiple apps" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app_prefix) + + expect(Shell).not_to have_received(:color) + .with(include("Any app starting with '#{app_prefix}'"), :red) + expect(Shell).not_to have_received(:color).with("rails", :red) + expect(Shell).not_to have_received(:color).with("postgres", :red) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).not_to include("cpl setup-app") + expect(result[:stdout]).not_to include("cpl apply-template") + end + end + + context "when there are apps missing" do + let!(:app_prefix) { dummy_test_app_prefix("info-with-missing-apps") } + let!(:app1) { dummy_test_app("info-with-missing-apps") } + let!(:app2) { dummy_test_app("info-with-missing-apps") } + + it "highlights single app with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app1) + + expect(Shell).to have_received(:color).with(app1, :red) + expect(Shell).to have_received(:color).with("rails", :red) + expect(Shell).to have_received(:color).with("postgres", :red) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).to include("`cpl setup-app -a #{app1}`") + end + + it "highlights multiple apps with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app_prefix) + + expect(Shell).to have_received(:color) + .with(include("Any app starting with '#{app_prefix}'"), :red) + expect(Shell).to have_received(:color).with("rails", :red).at_least(:once) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).not_to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + + it "highlights apps for single org with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-o", dummy_test_org) + + expect(Shell).to have_received(:color) + .with(include("Any app starting with '#{app_prefix}'"), :red) + expect(Shell).to have_received(:color).with("rails", :red).at_least(:once) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).not_to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + + it "highlights apps for multiple orgs with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info") + + expect(Shell).to have_received(:color) + .with(include("Any app starting with '#{app_prefix}'"), :red) + expect(Shell).to have_received(:color).with("rails", :red).at_least(:once) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).not_to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + end + + context "when there are workloads missing" do + let!(:app_prefix) { dummy_test_app_prefix("info-with-missing-workloads") } + let!(:app1) { dummy_test_app("info-with-missing-workloads", "1", create_if_not_exists: true) } + let!(:app2) { dummy_test_app("info-with-missing-workloads", "2", create_if_not_exists: true) } + + it "highlights workloads for single app with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app1) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with("rails", :red) + expect(Shell).to have_received(:color).with("postgres", :red) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app1}`") + end + + it "highlights workloads for multiple apps with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app_prefix) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app1}`") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app2}`") + end + + it "highlights workloads for single org with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-o", dummy_test_org) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app1}`") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app2}`") + end + + it "highlights workloads for multiple orgs with red" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info") + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("postgres", :red).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app1}`") + expect(result[:stdout]).to include("`cpl apply-template postgres -a #{app2}`") + end + end + + context "when there are extra workloads" do + let!(:app_prefix) { dummy_test_app_prefix("info-with-extra-workloads") } + let!(:app1) { dummy_test_app("info-with-extra-workloads", "1", create_if_not_exists: true) } + let!(:app2) { dummy_test_app("info-with-extra-workloads", "2", create_if_not_exists: true) } + + it "highlights workloads for single app with green" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app1) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with("rails", :red) + expect(Shell).not_to have_received(:color).with("postgres", :red) + expect(Shell).to have_received(:color).with("rails-with-non-app-image", :green) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).not_to include("- #{app2}") + expect(result[:stdout]).not_to include("cpl setup-app") + expect(result[:stdout]).not_to include("cpl apply-template") + end + + it "highlights workloads for multiple apps with green" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-a", app_prefix) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("rails-with-non-app-image", :green).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).not_to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + + it "highlights workloads for single org with green" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info", "-o", dummy_test_org) + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("rails-with-non-app-image", :green).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).not_to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + + it "highlights workloads for multiple orgs with green" do + allow(Shell).to receive(:color).and_call_original + + result = run_cpl_command("info") + + expect(Shell).not_to have_received(:color).with(app1, :red) + expect(Shell).not_to have_received(:color).with(app2, :red) + expect(Shell).to have_received(:color).with("rails-with-non-app-image", :green).at_least(:once) + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("- #{app1}") + expect(result[:stdout]).to include("- #{app2}") + expect(result[:stdout]).not_to include("`cpl setup-app -a #{app_prefix}-whatever`") + end + end +end diff --git a/spec/command/latest_image_spec.rb b/spec/command/latest_image_spec.rb new file mode 100644 index 00000000..622d551f --- /dev/null +++ b/spec/command/latest_image_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::LatestImage do + context "when no images have been built" do + let!(:app) { dummy_test_app } + + it "displays default image for app" do + result = run_cpl_command("latest-image", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("#{app}:NO_IMAGE_AVAILABLE") + end + end + + context "when images have been built" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "displays latest image for app" do + result = run_cpl_command("latest-image", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("#{app}:2") + end + end +end diff --git a/spec/command/logs_spec.rb b/spec/command/logs_spec.rb new file mode 100644 index 00000000..9dfb5948 --- /dev/null +++ b/spec/command/logs_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Logs do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + end + + context "when no workload is provided" do + it "displays logs for one-off workload", :slow do + result = nil + expected_regex = /Rails .+? application starting in production/ + + spawn_cpl_command("logs", "-a", app) do |it| + result = it.wait_for(expected_regex) + it.kill + end + + expect(result).to match(expected_regex) + end + end + + context "when workload is provided" do + it "displays logs for specific workload", :slow do + result = nil + expected_regex = /PostgreSQL init process complete/ + + spawn_cpl_command("logs", "-a", app, "--workload", "postgres") do |it| + result = it.wait_for(expected_regex) + it.kill + end + + expect(result).to match(expected_regex) + end + end +end diff --git a/spec/command/maintenance_off_spec.rb b/spec/command/maintenance_off_spec.rb index 86835ab6..52bbeb6c 100644 --- a/spec/command/maintenance_off_spec.rb +++ b/spec/command/maintenance_off_spec.rb @@ -3,77 +3,51 @@ require "spec_helper" describe Command::MaintenanceOff do - # rubocop:disable RSpec/AnyInstance - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") - allow_any_instance_of(described_class).to receive(:sleep).and_return(true) - end - # rubocop:enable RSpec/AnyInstance - - it "displays error if domain is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find domain. " \ - "Maintenance mode is only supported for domains that use path based routing mode " \ - "and have a route configured for the prefix '/' on either port 80 or 443.") + context "when app has no domain" do + let!(:app) { dummy_test_app("with-nothing") } - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + it "raises error" do + result = run_cpl_command("maintenance:off", "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find domain") + end end - it "displays error if maintenance workload is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find workload 'maintenance', " \ - "please create it with 'cpl apply-template maintenance -a my-app-staging'.") - - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) - - expect(Shell).to have_received(:abort).once - end + context "when maintenance workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } - it "does nothing if maintenance mode is already disabled", vcr: true do - expected_output = <<~OUTPUT - Maintenance mode is already disabled for app 'my-app-staging'. - OUTPUT + it "raises error" do + result = run_cpl_command("maintenance:off", "-a", app) - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'maintenance'") end - - expect(output).to eq(expected_output) end - it "disables maintenance mode", vcr: true do - expected_output = <<~OUTPUT - Starting workload 'postgres'... #{Shell.color('done!', :green)} - Starting workload 'redis'... #{Shell.color('done!', :green)} - Starting workload 'rails'... #{Shell.color('done!', :green)} + context "when maintenance workload exists" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } - Waiting for workload 'postgres' to be ready... #{Shell.color('done!', :green)} - Waiting for workload 'redis' to be ready... #{Shell.color('done!', :green)} - Waiting for workload 'rails' to be ready... #{Shell.color('done!', :green)} + before do + allow(Kernel).to receive(:sleep) - Switching workload for domain 'my-app-staging.example.com' to 'rails'... #{Shell.color('done!', :green)} + run_cpl_command!("ps:start", "-a", app, "--wait") + end - Stopping workload 'maintenance'... #{Shell.color('done!', :green)} + it "does nothing if maintenance mode is already disabled", :slow do + run_cpl_command!("maintenance:off", "-a", app) + result = run_cpl_command("maintenance:off", "-a", app) - Waiting for workload 'maintenance' to not be ready... #{Shell.color('done!', :green)} + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Maintenance mode is already disabled for app '#{app}'") + end - Maintenance mode disabled for app 'my-app-staging'. - OUTPUT + it "disables maintenance mode", :slow do + run_cpl_command!("maintenance:on", "-a", app) + result = run_cpl_command("maintenance:off", "-a", app) - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Maintenance mode disabled for app '#{app}'") end - - expect(output).to eq(expected_output) end end diff --git a/spec/command/maintenance_on_spec.rb b/spec/command/maintenance_on_spec.rb index 4a686825..dcc8c4fb 100644 --- a/spec/command/maintenance_on_spec.rb +++ b/spec/command/maintenance_on_spec.rb @@ -3,77 +3,51 @@ require "spec_helper" describe Command::MaintenanceOn do - # rubocop:disable RSpec/AnyInstance - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") - allow_any_instance_of(described_class).to receive(:sleep).and_return(true) - end - # rubocop:enable RSpec/AnyInstance - - it "displays error if domain is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find domain. " \ - "Maintenance mode is only supported for domains that use path based routing mode " \ - "and have a route configured for the prefix '/' on either port 80 or 443.") + context "when app has no domain" do + let!(:app) { dummy_test_app("with-nothing") } - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + it "raises error" do + result = run_cpl_command("maintenance:on", "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find domain") + end end - it "displays error if maintenance workload is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find workload 'maintenance', " \ - "please create it with 'cpl apply-template maintenance -a my-app-staging'.") - - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) - - expect(Shell).to have_received(:abort).once - end + context "when maintenance workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } - it "does nothing if maintenance mode is already enabled", vcr: true do - expected_output = <<~OUTPUT - Maintenance mode is already enabled for app 'my-app-staging'. - OUTPUT + it "raises error" do + result = run_cpl_command("maintenance:on", "-a", app) - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'maintenance'") end - - expect(output).to eq(expected_output) end - it "enables maintenance mode", vcr: true do - expected_output = <<~OUTPUT - Starting workload 'maintenance'... #{Shell.color('done!', :green)} + context "when maintenance workload exists" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } - Waiting for workload 'maintenance' to be ready... #{Shell.color('done!', :green)} + before do + allow(Kernel).to receive(:sleep) - Switching workload for domain 'my-app-staging.example.com' to 'maintenance'... #{Shell.color('done!', :green)} + run_cpl_command!("ps:start", "-a", app, "--wait") + end - Stopping workload 'rails'... #{Shell.color('done!', :green)} - Stopping workload 'redis'... #{Shell.color('done!', :green)} - Stopping workload 'postgres'... #{Shell.color('done!', :green)} + it "does nothing if maintenance mode is already enabled", :slow do + run_cpl_command!("maintenance:on", "-a", app) + result = run_cpl_command("maintenance:on", "-a", app) - Waiting for workload 'rails' to not be ready... #{Shell.color('done!', :green)} - Waiting for workload 'redis' to not be ready... #{Shell.color('done!', :green)} - Waiting for workload 'postgres' to not be ready... #{Shell.color('done!', :green)} + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Maintenance mode is already enabled for app '#{app}'") + end - Maintenance mode enabled for app 'my-app-staging'. - OUTPUT + it "enables maintenance mode", :slow do + run_cpl_command!("maintenance:off", "-a", app) + result = run_cpl_command("maintenance:on", "-a", app) - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Maintenance mode enabled for app '#{app}'") end - - expect(output).to eq(expected_output) end end diff --git a/spec/command/maintenance_set_page_spec.rb b/spec/command/maintenance_set_page_spec.rb index df0dfe97..b28ebe6b 100644 --- a/spec/command/maintenance_set_page_spec.rb +++ b/spec/command/maintenance_set_page_spec.rb @@ -3,44 +3,47 @@ require "spec_helper" describe Command::MaintenanceSetPage do - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") # rubocop:disable RSpec/AnyInstance - end + let!(:example_maintenance_page) { "https://example.com/maintenance.html" } - it "displays error if maintenance workload is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find workload 'maintenance', " \ - "please create it with 'cpl apply-template maintenance -a my-app-staging'.") + context "when maintenance workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } - args = ["https://example.com/maintenance.html", "-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + it "raises error" do + result = run_cpl_command("maintenance:set-page", example_maintenance_page, "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'maintenance'") + end end - it "does nothing if maintenance workload does not use shakacode image", vcr: true do - output = command_output do - args = ["https://example.com/maintenance.html", "-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + context "when maintenance workload uses external (non-shakacode) image" do + let!(:app) { dummy_test_app("with-external-maintenance-image") } + + before do + run_cpl_command!("apply-template", "gvc", "maintenance-with-external-image", "-a", app) end - expect(output).to be_empty - end + after do + run_cpl_command!("delete", "-a", app, "--yes") + end - it "sets page for maintenance mode", vcr: true do - expected_output = <<~OUTPUT - Setting 'https://example.com/maintenance.html' as the page for maintenance mode... #{Shell.color('done!', :green)} - OUTPUT + it "does nothing" do + result = run_cpl_command("maintenance:set-page", example_maintenance_page, "-a", app) - output = command_output do - args = ["https://example.com/maintenance.html", "-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(result[:status]).to eq(0) + expect(result[:stderr]).not_to include("Setting '#{example_maintenance_page}' as the page for maintenance mode") end + end + + context "when maintenance workload uses shakacode image" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } - expect(output).to eq(expected_output) + it "sets page for maintenance mode" do + result = run_cpl_command("maintenance:set-page", example_maintenance_page, "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]) + .to match(/Setting '#{example_maintenance_page}' as the page for maintenance mode[.]+? done!/) + end end end diff --git a/spec/command/maintenance_spec.rb b/spec/command/maintenance_spec.rb index e506e736..7e347d66 100644 --- a/spec/command/maintenance_spec.rb +++ b/spec/command/maintenance_spec.rb @@ -3,41 +3,40 @@ require "spec_helper" describe Command::Maintenance do - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") # rubocop:disable RSpec/AnyInstance - end - - it "displays error if domain is not found", vcr: true do - allow(Shell).to receive(:abort) - .with("Can't find domain. " \ - "Maintenance mode is only supported for domains that use path based routing mode " \ - "and have a route configured for the prefix '/' on either port 80 or 443.") + context "when app has no domain" do + let!(:app) { dummy_test_app("with-nothing") } - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + it "raises error" do + result = run_cpl_command("maintenance", "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find domain") + end end - it "displays 'on' if maintenance mode is enabled", vcr: true do - allow($stdout).to receive(:puts).with("on") + context "when app has domain" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + before do + allow(Kernel).to receive(:sleep) - expect($stdout).to have_received(:puts).once - end + run_cpl_command!("ps:start", "-a", app, "--wait") + end + + it "displays 'off' if maintenance mode is disabled", :slow do + run_cpl_command!("maintenance:off", "-a", app) + result = run_cpl_command("maintenance", "-a", app) - it "displays 'off' if maintenance mode is disabled", vcr: true do - allow($stdout).to receive(:puts).with("off") + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("off") + end - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + it "displays 'on' if maintenance mode is enabled", :slow do + run_cpl_command!("maintenance:on", "-a", app) + result = run_cpl_command("maintenance", "-a", app) - expect($stdout).to have_received(:puts).once + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("on") + end end end diff --git a/spec/command/no_command_spec.rb b/spec/command/no_command_spec.rb new file mode 100644 index 00000000..ffdd85e3 --- /dev/null +++ b/spec/command/no_command_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::NoCommand do + context "when called with nothing" do + it "displays help" do + result = run_cpl_command + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("cpl commands") + end + end + + context "when called with --version" do + it "displays version" do + result = run_cpl_command("--version") + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include(Cpl::VERSION) + end + end +end diff --git a/spec/command/open_console_spec.rb b/spec/command/open_console_spec.rb new file mode 100644 index 00000000..431e8fa2 --- /dev/null +++ b/spec/command/open_console_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::OpenConsole do + let!(:app) { dummy_test_app } + + context "when no workload is provided" do + it "opens app console on Control Plane" do + allow(Kernel).to receive(:exec) + + result = run_cpl_command("open-console", "-a", app) + + expected_url = %r{https://console.cpln.io/console/org/.+?/gvc/#{app}/-info} + expect(Kernel).to have_received(:exec).with(anything, match(expected_url)) + expect(result[:status]).to eq(0) + end + end + + context "when workload is provided" do + it "opens workload page on Control Plane" do + allow(Kernel).to receive(:exec) + + result = run_cpl_command("open-console", "-a", app, "--workload", "rails") + + expected_url = %r{https://console.cpln.io/console/org/.+?/gvc/#{app}/workload/rails/-info} + expect(Kernel).to have_received(:exec).with(anything, match(expected_url)) + expect(result[:status]).to eq(0) + end + end +end diff --git a/spec/command/open_spec.rb b/spec/command/open_spec.rb new file mode 100644 index 00000000..136273a9 --- /dev/null +++ b/spec/command/open_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Open do + context "when one-off workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("open", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when no workload is provided" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "opens endpoint of one-off workload" do + allow(Kernel).to receive(:exec) + + result = run_cpl_command("open", "-a", app) + + expected_url = %r{https://rails-.+?.cpln.app} + expect(Kernel).to have_received(:exec).with(anything, match(expected_url)) + expect(result[:status]).to eq(0) + end + end + + context "when workload is provided" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "opens endpoint of specific workload" do + allow(Kernel).to receive(:exec) + + result = run_cpl_command("open", "-a", app, "--workload", "postgres") + + expected_url = %r{https://postgres-.+?.cpln.app} + expect(Kernel).to have_received(:exec).with(anything, match(expected_url)) + expect(result[:status]).to eq(0) + end + end +end diff --git a/spec/command/promote_app_from_upstream_spec.rb b/spec/command/promote_app_from_upstream_spec.rb new file mode 100644 index 00000000..9ff3f393 --- /dev/null +++ b/spec/command/promote_app_from_upstream_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::PromoteAppFromUpstream do + context "when release script is not provided" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:upstream_app) { dummy_test_app } + let!(:app) { dummy_test_app("with-nothing") } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app + # Ideally, we should have a different org, but for testing purposes, this works + ENV["CPLN_ORG_UPSTREAM"] = dummy_test_org + + run_cpl_command!("apply-template", "gvc", "-a", upstream_app) + run_cpl_command!("apply-template", "gvc", "rails", "-a", app) + run_cpl_command!("build-image", "-a", upstream_app) + end + + after do + run_cpl_command!("delete", "-a", upstream_app, "--yes") + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "copies latest image from upstream, skips release script and deploys image", :slow do + result = run_cpl_command("promote-app-from-upstream", "-a", app, "--upstream-token", token) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:1'}) + expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'}) + expect(result[:stderr]).not_to include("Running release script") + expect(result[:stderr]).to match(%r{rails: https://rails-.+?.cpln.app}) + end + end + + context "when release script is invalid" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:upstream_app) { dummy_test_app } + let!(:app) { dummy_test_app("with-invalid-release-script") } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app + # Ideally, we should have a different org, but for testing purposes, this works + ENV["CPLN_ORG_UPSTREAM"] = dummy_test_org + ENV["APP_NAME"] = app + + run_cpl_command!("apply-template", "gvc", "-a", upstream_app) + run_cpl_command!("apply-template", "gvc", "rails", "-a", app) + run_cpl_command!("build-image", "-a", upstream_app) + end + + after do + run_cpl_command!("delete", "-a", upstream_app, "--yes") + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "copies latest image from upstream, fails to run release script and fails to deploy image", :slow do + result = run_cpl_command("promote-app-from-upstream", "-a", app, "--upstream-token", token) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:1'}) + expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'}) + expect(result[:stderr]).to include("Running release script") + expect(result[:stderr]).to include("Failed to run release script") + expect(result[:stderr]).not_to match(%r{rails: https://rails-.+?.cpln.app}) + end + end + + context "when release script is valid" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:upstream_app) { dummy_test_app } + let!(:app) { dummy_test_app } + + before do + ENV["CPLN_UPSTREAM"] = upstream_app + # Ideally, we should have a different org, but for testing purposes, this works + ENV["CPLN_ORG_UPSTREAM"] = dummy_test_org + ENV["APP_NAME"] = app + + run_cpl_command!("apply-template", "gvc", "-a", upstream_app) + run_cpl_command!("apply-template", "gvc", "rails", "postgres", "-a", app) + run_cpl_command!("build-image", "-a", upstream_app) + run_cpl_command!("ps:start", "-a", app, "--workload", "postgres", "--wait") + end + + after do + run_cpl_command!("delete", "-a", upstream_app, "--yes") + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "copies latest image from upstream, runs release script and deploys image", :slow do + result = run_cpl_command("promote-app-from-upstream", "-a", app, "--upstream-token", token) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(%r{Pulling image from '.+?/#{upstream_app}:1'}) + expect(result[:stderr]).to match(%r{Pushing image to '.+?/#{app}:1'}) + expect(result[:stderr]).to include("Running release script") + expect(result[:stderr]).not_to include("Failed to run release script") + expect(result[:stderr]).to match(%r{rails: https://rails-.+?.cpln.app}) + end + end +end diff --git a/spec/command/ps_restart_spec.rb b/spec/command/ps_restart_spec.rb new file mode 100644 index 00000000..ba786ba1 --- /dev/null +++ b/spec/command/ps_restart_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::PsRestart do + context "when any workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("ps:restart", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when all workloads exist" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + end + + it "restarts all workloads", :slow do + result = run_cpl_command("ps:restart", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Restarting workload 'rails'[.]+? done!/) + expect(result[:stderr]).to match(/Restarting workload 'postgres'[.]+? done!/) + end + + it "restarts specific workload", :slow do + result = run_cpl_command("ps:restart", "-a", app, "--workload", "rails") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Restarting workload 'rails'[.]+? done!/) + expect(result[:stderr]).not_to include("postgres") + end + end +end diff --git a/spec/command/ps_spec.rb b/spec/command/ps_spec.rb new file mode 100644 index 00000000..f6da50ac --- /dev/null +++ b/spec/command/ps_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Ps do + context "when app does not exist" do + let!(:app) { dummy_test_app } + + it "raises error" do + result = run_cpl_command("ps", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find app '#{app}'") + end + end + + context "when any workload does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("ps", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when no replicas are running" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + run_cpl_command!("ps:stop", "-a", app, "--wait") + end + + it "displays nothing", :slow do + result = run_cpl_command("ps", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to be_empty + end + end + + context "when replicas are running" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + end + + it "displays currently running replicas for all workloads", :slow do + result = run_cpl_command("ps", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("rails-") + expect(result[:stdout]).to include("postgres-") + end + + it "displays currently running replicas for specific workload", :slow do + result = run_cpl_command("ps", "-a", app, "--workload", "rails") + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include("rails-") + expect(result[:stdout]).not_to include("postgres-") + end + end +end diff --git a/spec/command/ps_start_spec.rb b/spec/command/ps_start_spec.rb new file mode 100644 index 00000000..ba0bf31c --- /dev/null +++ b/spec/command/ps_start_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::PsStart do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:stop", "-a", app, "--wait") + end + + it "starts all workloads", :slow do + result = run_cpl_command("ps:start", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Starting workload 'rails'[.]+? done!/) + expect(result[:stderr]).to match(/Starting workload 'postgres'[.]+? done!/) + end + + it "starts specific workload", :slow do + result = run_cpl_command("ps:start", "-a", app, "--workload", "rails") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Starting workload 'rails'[.]+? done!/) + expect(result[:stderr]).not_to include("postgres") + end + + it "starts all workloads and waits for them to be ready", :slow do + result = run_cpl_command("ps:start", "-a", app, "--wait") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Starting workload 'rails'[.]+? done!/) + expect(result[:stderr]).to match(/Starting workload 'postgres'[.]+? done!/) + expect(result[:stderr]).to match(/Waiting for workload 'rails' to be ready[.]+? done!/) + expect(result[:stderr]).to match(/Waiting for workload 'postgres' to be ready[.]+? done!/) + end +end diff --git a/spec/command/ps_stop_spec.rb b/spec/command/ps_stop_spec.rb new file mode 100644 index 00000000..d079f68a --- /dev/null +++ b/spec/command/ps_stop_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::PsStop do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + end + + it "stops all workloads", :slow do + result = run_cpl_command("ps:stop", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Stopping workload 'rails'[.]+? done!/) + expect(result[:stderr]).to match(/Stopping workload 'postgres'[.]+? done!/) + end + + it "stops specific workload", :slow do + result = run_cpl_command("ps:stop", "-a", app, "--workload", "rails") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Stopping workload 'rails'[.]+? done!/) + expect(result[:stderr]).not_to include("postgres") + end + + it "stops all workloads and waits for them to not be ready", :slow do + result = run_cpl_command("ps:stop", "-a", app, "--wait") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Stopping workload 'rails'[.]+? done!/) + expect(result[:stderr]).to match(/Stopping workload 'postgres'[.]+? done!/) + expect(result[:stderr]).to match(/Waiting for workload 'rails' to not be ready[.]+? done!/) + expect(result[:stderr]).to match(/Waiting for workload 'postgres' to not be ready[.]+? done!/) + end +end diff --git a/spec/command/ps_wait_spec.rb b/spec/command/ps_wait_spec.rb new file mode 100644 index 00000000..b2df291f --- /dev/null +++ b/spec/command/ps_wait_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::PsWait do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + run_cpl_command!("ps:start", "-a", app, "--wait") + run_cpl_command!("ps:restart", "-a", app) + end + + it "waits for all workloads to be ready", :slow do + result = run_cpl_command("ps:wait", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Waiting for workload 'rails' to be ready[.]+? done!/) + expect(result[:stderr]).to match(/Waiting for workload 'postgres' to be ready[.]+? done!/) + end + + it "waits for specific workload to be ready", :slow do + result = run_cpl_command("ps:wait", "-a", app, "--workload", "rails") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Waiting for workload 'rails' to be ready[.]+? done!/) + expect(result[:stderr]).not_to include("postgres") + end +end diff --git a/spec/command/run_cleanup_spec.rb b/spec/command/run_cleanup_spec.rb index fba75332..47a8f24f 100644 --- a/spec/command/run_cleanup_spec.rb +++ b/spec/command/run_cleanup_spec.rb @@ -3,180 +3,177 @@ require "spec_helper" describe Command::RunCleanup do - before do - allow(ENV).to receive(:fetch).with("CPLN_ENDPOINT", "https://api.cpln.io").and_return("https://api.cpln.io") - allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token") - allow(ENV).to receive(:fetch).with("CPLN_ORG", nil).and_return(nil) - allow(ENV).to receive(:fetch).with("CPLN_APP", nil).and_return(nil) - allow_any_instance_of(Config).to receive(:config_file_path).and_return("spec/fixtures/config.yml") # rubocop:disable RSpec/AnyInstance - - Timecop.freeze(Time.local(2023, 5, 15)) + context "when 'stale_run_workload_created_days' is not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("run:cleanup", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'stale_run_workload_created_days'") + end end - it "displays error if 'stale_run_workload_created_days' is not set" do - allow(Shell).to receive(:abort).with("Can't find option 'stale_run_workload_created_days' " \ - "for app 'my-app-other' in 'controlplane.yml'.") + context "when there are no stale run workloads to delete" do + let!(:app) { dummy_test_app } - args = ["-a", "my-app-other"] - Cpl::Cli.start([described_class::NAME, *args]) + it "displays message" do + result = run_cpl_command("run:cleanup", "-a", app) - expect(Shell).to have_received(:abort).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No stale run workloads found") + end end - it "displays empty message", vcr: true do - expected_output = <<~OUTPUT - No stale run workloads found. - OUTPUT + context "when run workload matches defined workload exactly" do + let!(:app) { dummy_test_app("with-fake-run-workload") } - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + before do + run_cpl_command!("apply-template", "gvc", "fake-run-12345", "-a", app) end - expect(output).to eq(expected_output) + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "lists nothing" do + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app) + travel_back + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No stale run workloads found") + end end - it "lists stale run workloads", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 4 run workloads?") - .and_return(false) + context "when run workloads do not match naming pattern exactly" do + let!(:app) { dummy_test_app } - expected_output = <<~OUTPUT - Stale run workloads: - rails-run-4137 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-run-7025 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - rails-runner-4985 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-runner-6669 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - OUTPUT + before do + run_cpl_command!("apply-template", "gvc", "fake-run-12345", "fake-runner-12345", "-a", app) + end - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + after do + run_cpl_command!("delete", "-a", app, "--yes") end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) - end + it "lists nothing" do + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app) + travel_back - it "lists stale run workloads for all apps that start with name", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 4 run workloads?") - .and_return(false) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No stale run workloads found") + end + end - expected_output = <<~OUTPUT - Stale run workloads: - my-app-review-1 - rails-run-1527 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-run-9213 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - my-app-review-1 - rails-runner-8931 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-runner-1273 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - OUTPUT + context "when run workloads are not older than 'stale_run_workload_created_days'" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } - output = command_output do - args = ["-a", "my-app-review"] - Cpl::Cli.start([described_class::NAME, *args]) + before do + create_run_workloads(app) end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) + it "lists nothing", :slow do + result = run_cpl_command("run:cleanup", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("No stale run workloads found") + end end - it "deletes stale run workloads", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 4 run workloads?") - .and_return(true) + context "when there are stale run workloads to delete" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + before do + create_run_workloads(app) + end - expected_output = <<~OUTPUT - Stale run workloads: - rails-run-4137 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-run-7025 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - rails-runner-4985 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-runner-6669 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) + it "asks for confirmation and does nothing", :slow do + allow(Shell).to receive(:confirm).with(match(/\d+ run workloads/)).and_return(false) - Deleting run workload 'rails-run-4137'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-run-7025'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-runner-4985'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-runner-6669'... #{Shell.color('done!', :green)} - OUTPUT + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app) + travel_back - output = command_output do - args = ["-a", "my-app-staging"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).not_to include("Deleting run workload") end - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) - end + it "asks for confirmation and deletes stale run workloads", :slow do + allow(Shell).to receive(:confirm).with(match(/\d+ run workloads/)).and_return(true) - it "deletes stale run workloads for all apps that start with name", vcr: true do - allow(Shell).to receive(:confirm).with("\nAre you sure you want to delete these 4 run workloads?") - .and_return(true) + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app) + travel_back - expected_output = <<~OUTPUT - Stale run workloads: - my-app-review-1 - rails-run-1527 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-run-9213 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - my-app-review-1 - rails-runner-8931 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-runner-1273 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting run workload '#{app}: rails-run-\d{4}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting run workload '#{app}: rails-runner-\d{4}'[.]+? done!/) + end - Deleting run workload 'my-app-review-1 - rails-run-1527'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-2 - rails-run-9213'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-1 - rails-runner-8931'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-2 - rails-runner-1273'... #{Shell.color('done!', :green)} - OUTPUT + it "skips confirmation and deletes stale run workloads", :slow do + allow(Shell).to receive(:confirm).and_return(false) - output = command_output do - args = ["-a", "my-app-review"] - Cpl::Cli.start([described_class::NAME, *args]) - end + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app, "--yes") + travel_back - expect(Shell).to have_received(:confirm).once - expect(output).to eq(expected_output) + expect(Shell).not_to have_received(:confirm) + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Deleting run workload '#{app}: rails-run-\d{4}'[.]+? done!/) + expect(result[:stderr]).to match(/Deleting run workload '#{app}: rails-runner-\d{4}'[.]+? done!/) + end end - it "skips delete confirmation", vcr: true do - allow(Shell).to receive(:confirm) + context "with multiple apps" do + let!(:app_prefix) { dummy_test_app_prefix("full") } + let!(:app1) { dummy_test_app("full", "1", create_if_not_exists: true) } + let!(:app2) { dummy_test_app("full", "2", create_if_not_exists: true) } - expected_output = <<~OUTPUT - Stale run workloads: - rails-run-4137 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-run-7025 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - rails-runner-4985 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - rails-runner-6669 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) + before do + create_run_workloads(app1) + create_run_workloads(app2) + end + + it "lists correct run workloads from exact app", :slow do + allow(Shell).to receive(:confirm).with(match(/\d+ run workloads/)).and_return(false) - Deleting run workload 'rails-run-4137'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-run-7025'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-runner-4985'... #{Shell.color('done!', :green)} - Deleting run workload 'rails-runner-6669'... #{Shell.color('done!', :green)} - OUTPUT + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app1) + travel_back - output = command_output do - args = ["-a", "my-app-staging", "-y"] - Cpl::Cli.start([described_class::NAME, *args]) + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app1}: rails-run-\d{4}/) + expect(result[:stderr]).to match(/- #{app1}: rails-runner-\d{4}/) end - expect(Shell).not_to have_received(:confirm) - expect(output).to eq(expected_output) - end + it "lists correct run workloads from all matching apps", :slow do + allow(Shell).to receive(:confirm).with(match(/\d+ run workloads/)).and_return(false) - it "skips delete confirmation for all apps that start with name", vcr: true do - allow(Shell).to receive(:confirm) + travel_to_days_later(3) + result = run_cpl_command("run:cleanup", "-a", app_prefix) + travel_back - expected_output = <<~OUTPUT - Stale run workloads: - my-app-review-1 - rails-run-1527 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-run-9213 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) - my-app-review-1 - rails-runner-8931 (#{Shell.color('2023-05-10T12:00:00+00:00 - 4 days ago', :red)}) - my-app-review-2 - rails-runner-1273 (#{Shell.color('2023-05-13T00:00:00+00:00 - 2 days ago', :red)}) + expect(Shell).to have_received(:confirm).once + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/- #{app1}: rails-run-\d{4}/) + expect(result[:stderr]).to match(/- #{app1}: rails-runner-\d{4}/) + expect(result[:stderr]).to match(/- #{app2}: rails-run-\d{4}/) + expect(result[:stderr]).to match(/- #{app2}: rails-runner-\d{4}/) + end + end - Deleting run workload 'my-app-review-1 - rails-run-1527'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-2 - rails-run-9213'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-1 - rails-runner-8931'... #{Shell.color('done!', :green)} - Deleting run workload 'my-app-review-2 - rails-runner-1273'... #{Shell.color('done!', :green)} - OUTPUT + def create_run_workloads(app) + spawn_cpl_command("run", "-a", app, wait_for_process: false, &:wait_for_prompt) - output = command_output do - args = ["-a", "my-app-review", "-y"] - Cpl::Cli.start([described_class::NAME, *args]) + cmd = "\"bash -c 'while true; do sleep 1; done'\"" + expected_regex = /STARTED RUNNER SCRIPT/ + spawn_cpl_command("run:detached", "-a", app, "--", cmd, wait_for_process: false) do |it| + it.wait_for(expected_regex) end - - expect(Shell).not_to have_received(:confirm) - expect(output).to eq(expected_output) end end diff --git a/spec/command/run_detached_spec.rb b/spec/command/run_detached_spec.rb new file mode 100644 index 00000000..c68fd79b --- /dev/null +++ b/spec/command/run_detached_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::RunDetached do + context "when workload to clone does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("run:detached", "-a", app, "--", "ls") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when workload to clone exists" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "keeps retrying until MAX_RETRIES if runtime error happens", :slow do + stub_const("Command::RunDetached::MAX_RETRIES", 3) + allow_any_instance_of(described_class).to receive(:print_uniq_logs).and_raise(RuntimeError, "Runtime error.") # rubocop:disable RSpec/AnyInstance + + result = run_cpl_command("run:detached", "-a", app, "--", "ls") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Retrying").exactly(3).times + expect(result[:stderr]).to include("Exiting") + end + + it "deletes workload if finished with success", :slow do + result = run_cpl_command("run:detached", "-a", app, "--", "ls") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Gemfile") + expect(result[:stderr]).to include("DELETING WORKLOAD") + end + + it "deletes workload if finished with failure by default", :slow do + result = run_cpl_command("run:detached", "-a", app, "--", "nonexistent") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("CRASHED") + expect(result[:stderr]).to include("DELETING WORKLOAD") + end + + it "does not delete workload if finished with failure and --no-clean-on-failure is provided", :slow do + result = run_cpl_command("run:detached", "-a", app, "--no-clean-on-failure", "--", "nonexistent") + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("CRASHED") + expect(result[:stderr]).not_to include("DELETING WORKLOAD") + end + end + + context "when specifying image" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs with latest image", :slow do + result = run_cpl_command("run:detached", "-a", app, "--image", "latest", "--", "echo $CPLN_IMAGE") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(%r{/org/.+?/image/#{app}:2}) + end + + it "clones workload and runs with specific image", :slow do + result = run_cpl_command("run:detached", "-a", app, "--image", "#{app}:1", "--", "echo $CPLN_IMAGE") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(%r{/org/.+?/image/#{app}:1}) + end + end + + context "when specifying token" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs with remote token", :slow do + cmd = "bash -c 'if [ \"$CPLN_TOKEN\" = \"#{token}\" ]; then echo \"LOCAL\"; else echo \"REMOTE\"; fi'" + result = run_cpl_command("run:detached", "-a", app, "--", cmd) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("REMOTE") + end + + it "clones workload and runs with local token", :slow do + cmd = "bash -c 'if [ \"$CPLN_TOKEN\" = \"#{token}\" ]; then echo \"LOCAL\"; else echo \"REMOTE\"; fi'" + result = run_cpl_command("run:detached", "-a", app, "--use-local-token", "--", cmd) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("LOCAL") + end + end +end diff --git a/spec/command/run_spec.rb b/spec/command/run_spec.rb new file mode 100644 index 00000000..4ee013ad --- /dev/null +++ b/spec/command/run_spec.rb @@ -0,0 +1,170 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Run do + context "when workload to clone does not exist" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("run", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find workload 'rails'") + end + end + + context "when workload to clone exists" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs bash by default", :slow do + result = nil + expected_regex = /Gemfile/ + + spawn_cpl_command("run", "-a", app) do |it| + it.wait_for_prompt + it.type("ls") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + + it "clones workload and runs provided command", :slow do + result = nil + expected_regex = /Gemfile/ + + spawn_cpl_command("run", "-a", app, "--", "ls") do |it| + result = it.wait_for(expected_regex) + end + + expect(result).to match(expected_regex) + end + end + + context "when specifying image" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs with latest image", :slow do + result = nil + expected_regex = %r{/org/.+?/image/#{app}:2} + + spawn_cpl_command("run", "-a", app, "--image", "latest") do |it| + it.wait_for_prompt + it.type("echo $CPLN_IMAGE") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + + it "clones workload and runs with specific image", :slow do + result = nil + expected_regex = %r{/org/.+?/image/#{app}:1} + + spawn_cpl_command("run", "-a", app, "--image", "#{app}:1") do |it| + it.wait_for_prompt + it.type("echo $CPLN_IMAGE") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + end + + context "when specifying token" do + let!(:token) { Shell.cmd("cpln", "profile", "token", "default")[:output].strip } + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs with remote token", :slow do + result = nil + expected_regex = /REMOTE/ + + spawn_cpl_command("run", "-a", app) do |it| + it.wait_for_prompt + it.type("if [ \"$CPLN_TOKEN\" = \"#{token}\" ]; then echo \"LOCAL\"; else echo \"REMOTE\"; fi") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + + it "clones workload and runs with local token", :slow do + result = nil + expected_regex = /LOCAL/ + + spawn_cpl_command("run", "-a", app, "--use-local-token") do |it| + it.wait_for_prompt + it.type("if [ \"$CPLN_TOKEN\" = \"#{token}\" ]; then echo \"LOCAL\"; else echo \"REMOTE\"; fi") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + end + + context "when 'fix_terminal_size' is provided" do + let!(:app) { dummy_test_app("with-fix-terminal-size") } + + before do + run_cpl_command!("apply-template", "gvc", "rails", "-a", app) + run_cpl_command!("build-image", "-a", app) + run_cpl_command!("deploy-image", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "clones workload and runs with fixed terminal size", :slow do + result = nil + expected_regex = /10 150/ + + spawn_cpl_command("run", "-a", app, stty_rows: 10, stty_cols: 150) do |it| + it.wait_for_prompt + it.type("stty size") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + end + + context "when terminal size is provided" do + let!(:app) { dummy_test_app("full", create_if_not_exists: true) } + + it "clones workload and runs with provided terminal size", :slow do + result = nil + expected_regex = /20 300/ + + spawn_cpl_command("run", "-a", app, "--terminal-size", "20,300") do |it| + it.wait_for_prompt + it.type("stty size") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + + it "clones workload and fails to run with provided terminal size due to invalid format", :slow do + result = nil + expected_regex = /0 0/ + + spawn_cpl_command("run", "-a", app, "--terminal-size", "'20 300'") do |it| + it.wait_for_prompt + it.type("stty size") + result = it.wait_for(expected_regex) + it.type("exit") + end + + expect(result).to match(expected_regex) + end + end +end diff --git a/spec/command/setup_app_spec.rb b/spec/command/setup_app_spec.rb new file mode 100644 index 00000000..f517261f --- /dev/null +++ b/spec/command/setup_app_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::SetupApp do + context "when 'setup_app_templates' is not defined" do + let!(:app) { dummy_test_app("with-nothing") } + + it "raises error" do + result = run_cpl_command("setup-app", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't find option 'setup_app_templates'") + end + end + + context "when app already exists" do + let!(:app) { dummy_test_app("default", create_if_not_exists: true) } + + it "raises error" do + result = run_cpl_command("setup-app", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("App '#{app}' already exists") + end + end + + context "when skipping secret access binding" do + let!(:app) { dummy_test_app } + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "applies templates from 'setup_app_templates'" do + result = run_cpl_command("setup-app", "-a", app, "--skip-secret-access-binding") + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to include("Created items") + expect(result[:stderr]).to include("[app] #{app}") + expect(result[:stderr]).to include("[identity] #{app}-identity") + expect(result[:stderr]).to include("[workload] rails") + expect(result[:stderr]).to include("[workload] postgres") + expect(result[:stderr]).not_to include("Failed to apply templates") + end + end + + context "when identity or policy does not exist" do + let!(:app) { dummy_test_app("without-identity") } + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "raises error" do + result = run_cpl_command("setup-app", "-a", app) + + expect(result[:status]).not_to eq(0) + expect(result[:stderr]).to include("Can't bind identity to policy") + end + end + + context "when identity and policy exist" do + let!(:app) { dummy_test_app } + + before do + run_cpl_command!("apply-template", "secrets-policy", "-a", app) + end + + after do + run_cpl_command!("delete", "-a", app, "--yes") + end + + it "binds identity to policy" do + result = run_cpl_command("setup-app", "-a", app) + + expect(result[:status]).to eq(0) + expect(result[:stderr]).to match(/Binding identity to policy[.]+? done!/) + end + end +end diff --git a/spec/command/version_spec.rb b/spec/command/version_spec.rb new file mode 100644 index 00000000..0ecbdd57 --- /dev/null +++ b/spec/command/version_spec.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Command::Version do + it "displays version" do + result = run_cpl_command("version") + + expect(result[:status]).to eq(0) + expect(result[:stdout]).to include(Cpl::VERSION) + end +end diff --git a/spec/core/controlplane_api_direct_spec.rb b/spec/core/controlplane_api_direct_spec.rb index f617668d..8cbe8159 100644 --- a/spec/core/controlplane_api_direct_spec.rb +++ b/spec/core/controlplane_api_direct_spec.rb @@ -34,6 +34,10 @@ described_class.remove_class_variable(:@@api_token) if described_class.class_variable_defined?(:@@api_token) end + after do + described_class.remove_class_variable(:@@api_token) if described_class.class_variable_defined?(:@@api_token) + end + it "returns token from CPLN_TOKEN" do allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return("token_1") @@ -45,7 +49,7 @@ it "returns token from 'cpln profile token'" do allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return(nil) - allow(described_instance).to receive(:`).with("cpln profile token").and_return("token_2") + allow(Shell).to receive(:cmd).with("cpln", "profile", "token").and_return({ output: "token_2" }) result = described_instance.api_token @@ -55,7 +59,7 @@ it "raises error if token is not found" do allow(ENV).to receive(:fetch).with("CPLN_TOKEN", nil).and_return(nil) - allow(described_instance).to receive(:`).with("cpln profile token").and_return("") + allow(Shell).to receive(:cmd).with("cpln", "profile", "token").and_return({ output: "" }) message = "Unknown API token format. " \ "Please re-run 'cpln profile login' or set the correct CPLN_TOKEN env variable." diff --git a/spec/core/controlplane_spec.rb b/spec/core/controlplane_spec.rb new file mode 100644 index 00000000..86fa620e --- /dev/null +++ b/spec/core/controlplane_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Controlplane do + let!(:fake_config) { Struct.new(:app, :org).new("my-app", "my-org") } + let!(:described_instance) { described_class.new(fake_config) } + + describe "#build_command" do + let!(:original_cmd) { "cmd" } + + before do + allow(ENV).to receive(:fetch).with("HIDE_COMMAND_OUTPUT", nil).and_return(nil) + allow(Shell).to receive(:should_hide_output?).and_return(false) + end + + it "does not hide anything by default" do + cmd = described_instance.send(:build_command, original_cmd) + + expect(cmd).to eq(original_cmd) + end + + it "does not hide anything when 'output_mode' is :all" do + cmd = described_instance.send(:build_command, original_cmd, output_mode: :all) + + expect(cmd).to eq(original_cmd) + end + + it "hides stdout when 'output_mode' is :errors_only" do + cmd = described_instance.send(:build_command, original_cmd, output_mode: :errors_only) + + expect(cmd).to eq("#{original_cmd} > /dev/null") + end + + it "hides everything when 'output_mode' is :none" do + cmd = described_instance.send(:build_command, original_cmd, output_mode: :none) + + expect(cmd).to eq("#{original_cmd} > /dev/null 2>&1") + end + + it "hides everything when 'HIDE_COMMAND_OUTPUT' env var is set to 'true'" do + allow(ENV).to receive(:fetch).with("HIDE_COMMAND_OUTPUT", nil).and_return("true") + + cmd = described_instance.send(:build_command, original_cmd) + + expect(cmd).to eq("#{original_cmd} > /dev/null 2>&1") + end + + it "provided 'output_mode' overrides 'HIDE_COMMAND_OUTPUT' env var" do + allow(ENV).to receive(:fetch).with("HIDE_COMMAND_OUTPUT", nil).and_return("true") + + cmd = described_instance.send(:build_command, original_cmd, output_mode: :all) + + expect(cmd).to eq(original_cmd) + end + + it "hides stdout when 'Shell.should_hide_output?' is true" do + allow(Shell).to receive(:should_hide_output?).and_return(true) + + cmd = described_instance.send(:build_command, original_cmd) + + expect(cmd).to eq("#{original_cmd} > /dev/null") + end + + it "raises error when 'output_mode' is invalid" do + expect do + described_instance.send(:build_command, original_cmd, output_mode: :invalid) + end.to raise_error("Invalid command output mode 'invalid'.") + end + end +end diff --git a/spec/cpl_spec.rb b/spec/cpl_spec.rb index 991d88d8..5ac040bf 100644 --- a/spec/cpl_spec.rb +++ b/spec/cpl_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "spec_helper" + commands = Command::Base.all_commands options_by_key_name = Command::Base.all_options_by_key_name diff --git a/spec/dummy/Dockerfile b/spec/dummy/.controlplane/Dockerfile similarity index 92% rename from spec/dummy/Dockerfile rename to spec/dummy/.controlplane/Dockerfile index 584c37a0..cc713284 100644 --- a/spec/dummy/Dockerfile +++ b/spec/dummy/.controlplane/Dockerfile @@ -5,14 +5,13 @@ ARG RUBY_VERSION=3.1.2 FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base # Rails app lives here -WORKDIR /rails +WORKDIR /app # Set production environment ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ - BUNDLE_WITHOUT="development" - + BUNDLE_WITHOUT="development test" # Throw-away build stage to reduce size of final image FROM base as build @@ -49,7 +48,6 @@ RUN bundle exec bootsnap precompile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile - # Final stage for app image FROM base @@ -60,15 +58,16 @@ RUN apt-get update -qq && \ # Copy built artifacts: gems, application COPY --from=build /usr/local/bundle /usr/local/bundle -COPY --from=build /rails /rails +COPY --from=build /app /app # Run and own only the runtime files as a non-root user for security RUN useradd rails --create-home --shell /bin/bash && \ chown -R rails:rails db log storage tmp USER rails:rails -# Entrypoint prepares the database. -ENTRYPOINT ["/rails/bin/docker-entrypoint"] +# Entrypoint prepares the database +COPY .controlplane/entrypoint.sh ./ +ENTRYPOINT ["/app/entrypoint.sh"] # Start the server by default, this can be overwritten at runtime EXPOSE 3000 diff --git a/spec/dummy/.controlplane/Dockerfile.invalid b/spec/dummy/.controlplane/Dockerfile.invalid new file mode 100644 index 00000000..f86d9133 --- /dev/null +++ b/spec/dummy/.controlplane/Dockerfile.invalid @@ -0,0 +1,7 @@ +# syntax = docker/dockerfile:1 + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=3.1.2 +FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base + +RUN nonexistent diff --git a/spec/dummy/.controlplane/controlplane.yml b/spec/dummy/.controlplane/controlplane.yml new file mode 100644 index 00000000..698d03a9 --- /dev/null +++ b/spec/dummy/.controlplane/controlplane.yml @@ -0,0 +1,204 @@ +aliases: + common: &common + allow_org_override_by_env: true + + default_location: aws-us-east-2 + + one_off_workload: rails + app_workloads: + - rails + additional_workloads: + - postgres + +apps: + dummy-test: + <<: *common + + match_if_app_name_starts_with: true + image_retention_max_qty: 3 + image_retention_days: 30 + stale_app_image_deployed_days: 30 + stale_run_workload_created_days: 3 + upstream: dummy-test-upstream + release_script: release.sh + default_domain: cpl.rafaelgomes.xyz + maintenance_workload: maintenance + setup_app_templates: + - gvc + - rails + - postgres + + dummy-test-with-nothing: + <<: *common + + match_if_app_name_starts_with: true + + dummy-test-default: + <<: *common + + match_if_app_name_starts_with: true + default_domain: cpl.rafaelgomes.xyz + setup_app_templates: + - gvc + + dummy-test-with-rails: + <<: *common + + match_if_app_name_starts_with: true + setup_app_templates: + - gvc + - rails + + dummy-test-full: + <<: *common + + match_if_app_name_starts_with: true + stale_run_workload_created_days: 3 + default_domain: cpl.rafaelgomes.xyz + setup_app_templates: + - gvc + - rails + - postgres + - maintenance + + dummy-test-with-nonexistent-dockerfile: + <<: *common + + match_if_app_name_starts_with: true + dockerfile: Dockerfile.nonexistent + + dummy-test-with-invalid-dockerfile: + <<: *common + + match_if_app_name_starts_with: true + dockerfile: Dockerfile.invalid + + dummy-test-with-image-retention: + <<: *common + + match_if_app_name_starts_with: true + image_retention_max_qty: 3 + image_retention_days: 30 + setup_app_templates: + - gvc + + dummy-test-with-image-retention-max-qty: + <<: *common + + match_if_app_name_starts_with: true + image_retention_max_qty: 3 + + dummy-test-with-image-retention-days: + <<: *common + + match_if_app_name_starts_with: true + image_retention_days: 30 + + dummy-test-with-stale-app-image-deployed-days: + <<: *common + + match_if_app_name_starts_with: true + stale_app_image_deployed_days: 30 + + dummy-test-with-undefined-upstream: + <<: *common + + match_if_app_name_starts_with: true + upstream: undefined + + dummy-test-without-org: + <<: *common + + match_if_app_name_starts_with: true + cpln_org: + + dummy-test-with-rails-with-non-app-image: + <<: *common + + match_if_app_name_starts_with: true + release_script: release.sh + app_workloads: + - rails + - rails-with-non-app-image + setup_app_templates: + - gvc + - rails + - postgres + - rails-with-non-app-image + + dummy-test-with-nonexistent-release-script: + <<: *common + + match_if_app_name_starts_with: true + release_script: release-nonexistent.sh + + dummy-test-with-invalid-release-script: + <<: *common + + match_if_app_name_starts_with: true + upstream: dummy-test-upstream + release_script: release-invalid.sh + + dummy-test-with-external-maintenance-image: + <<: *common + + match_if_app_name_starts_with: true + maintenance_workload: maintenance-with-external-image + + dummy-test-with-fix-terminal-size: + <<: *common + + match_if_app_name_starts_with: true + fix_terminal_size: true + + dummy-test-with-fake-run-workload: + <<: *common + + match_if_app_name_starts_with: true + stale_run_workload_created_days: 3 + additional_workloads: + - fake-run-12345 + + dummy-test-without-identity: + <<: *common + + match_if_app_name_starts_with: true + setup_app_templates: + - gvc-without-identity + + dummy-test-info: + <<: *common + + match_if_app_name_starts_with: true + + dummy-test-info-with-nothing-missing: + <<: *common + + match_if_app_name_starts_with: true + setup_app_templates: + - gvc + - rails + - postgres + + dummy-test-info-with-missing-apps: + <<: *common + + match_if_app_name_starts_with: true + + dummy-test-info-with-missing-workloads: + <<: *common + + match_if_app_name_starts_with: true + setup_app_templates: + - gvc + - rails + + dummy-test-info-with-extra-workloads: + <<: *common + + match_if_app_name_starts_with: true + setup_app_templates: + - gvc + - rails + - postgres + - rails-with-non-app-image diff --git a/spec/dummy/.controlplane/entrypoint.sh b/spec/dummy/.controlplane/entrypoint.sh new file mode 100755 index 00000000..7baa04c8 --- /dev/null +++ b/spec/dummy/.controlplane/entrypoint.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +echo "Starting entrypoint.sh..." + +wait_for_service() +{ + until curl -I -sS $1 2>&1 | grep -q "Empty reply from server"; do + echo " - $1 is unavailable, sleeping..." + sleep 1 + done + + echo " - $1 is available" +} + +wait_for_services() +{ + echo "Waiting for services..." + + wait_for_service $(echo $DATABASE_URL | sed -e 's|^.*@||' -e 's|/.*$||') +} + +wait_for_services + +# If running the rails server then create or migrate existing database +if [ "${1}" = "./bin/rails" ] && [ "${2}" = "server" ]; then + echo "Preparing database..." + ./bin/rails db:prepare +fi + +echo "Finishing entrypoint.sh, executing '$@'..." + +exec "$@" diff --git a/spec/dummy/.controlplane/release-invalid.sh b/spec/dummy/.controlplane/release-invalid.sh new file mode 100644 index 00000000..15948564 --- /dev/null +++ b/spec/dummy/.controlplane/release-invalid.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cpl run:detached -a $APP_NAME --image latest -- bundle exec rake db:nonexistent diff --git a/spec/dummy/.controlplane/release.sh b/spec/dummy/.controlplane/release.sh new file mode 100644 index 00000000..3cbe21c4 --- /dev/null +++ b/spec/dummy/.controlplane/release.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cpl run:detached -a $APP_NAME --image latest -- bundle exec rake db:prepare diff --git a/spec/dummy/.controlplane/templates/detached-volume.yml b/spec/dummy/.controlplane/templates/detached-volume.yml new file mode 100644 index 00000000..6ac4b477 --- /dev/null +++ b/spec/dummy/.controlplane/templates/detached-volume.yml @@ -0,0 +1,6 @@ +kind: volumeset +name: detached-volume +spec: + fileSystemType: ext4 + performanceClass: general-purpose-ssd + initialCapacity: 10 diff --git a/spec/dummy/.controlplane/templates/fake-run-12345.yml b/spec/dummy/.controlplane/templates/fake-run-12345.yml new file mode 100644 index 00000000..0631ca5b --- /dev/null +++ b/spec/dummy/.controlplane/templates/fake-run-12345.yml @@ -0,0 +1,26 @@ +kind: workload +name: fake-run-12345 +spec: + type: standard + containers: + - name: rails + cpu: 512m + memory: 1Gi + inheritEnv: true + image: {{APP_IMAGE_LINK}} + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 + outboundAllowCIDR: + - 0.0.0.0/0 + identityLink: {{APP_IDENTITY_LINK}} diff --git a/spec/dummy/.controlplane/templates/fake-runner-12345.yml b/spec/dummy/.controlplane/templates/fake-runner-12345.yml new file mode 100644 index 00000000..56440ba5 --- /dev/null +++ b/spec/dummy/.controlplane/templates/fake-runner-12345.yml @@ -0,0 +1,26 @@ +kind: workload +name: fake-runner-12345 +spec: + type: standard + containers: + - name: rails + cpu: 512m + memory: 1Gi + inheritEnv: true + image: {{APP_IMAGE_LINK}} + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 + outboundAllowCIDR: + - 0.0.0.0/0 + identityLink: {{APP_IDENTITY_LINK}} diff --git a/spec/dummy/.controlplane/templates/gvc-with-all-variables.yml b/spec/dummy/.controlplane/templates/gvc-with-all-variables.yml new file mode 100644 index 00000000..367ec91d --- /dev/null +++ b/spec/dummy/.controlplane/templates/gvc-with-all-variables.yml @@ -0,0 +1,30 @@ +kind: gvc +name: {{APP_NAME}} +spec: + env: + - name: ORG + value: {{APP_ORG}} + - name: NAME + value: {{APP_NAME}} + - name: LOCATION + value: {{APP_LOCATION}} + - name: LOCATION_LINK + value: {{APP_LOCATION_LINK}} + - name: IMAGE + value: {{APP_IMAGE}} + - name: IMAGE_LINK + value: {{APP_IMAGE_LINK}} + - name: IDENTITY + value: {{APP_IDENTITY}} + - name: IDENTITY_LINK + value: {{APP_IDENTITY_LINK}} + - name: SECRETS + value: {{APP_SECRETS}} + - name: SECRETS_POLICY + value: {{APP_SECRETS_POLICY}} + staticPlacement: + locationLinks: + - {{APP_LOCATION_LINK}} +--- +kind: identity +name: {{APP_IDENTITY}} diff --git a/spec/dummy/.controlplane/templates/gvc-with-deprecated-variables.yml b/spec/dummy/.controlplane/templates/gvc-with-deprecated-variables.yml new file mode 100644 index 00000000..190604e2 --- /dev/null +++ b/spec/dummy/.controlplane/templates/gvc-with-deprecated-variables.yml @@ -0,0 +1,18 @@ +kind: gvc +name: {{APP_NAME}} +spec: + env: + - name: ORG + value: APP_ORG + - name: NAME + value: APP_GVC + - name: LOCATION + value: APP_LOCATION + - name: IMAGE + value: APP_IMAGE + staticPlacement: + locationLinks: + - {{APP_LOCATION_LINK}} +--- +kind: identity +name: {{APP_IDENTITY}} diff --git a/spec/dummy/.controlplane/templates/gvc-without-identity.yml b/spec/dummy/.controlplane/templates/gvc-without-identity.yml new file mode 100644 index 00000000..abc4333d --- /dev/null +++ b/spec/dummy/.controlplane/templates/gvc-without-identity.yml @@ -0,0 +1,11 @@ +kind: gvc +name: {{APP_NAME}} +spec: + env: + - name: DATABASE_URL + value: postgres://postgres:password@postgres.{{APP_NAME}}.cpln.local:5432/{{APP_NAME}} + - name: SECRET_KEY_BASE + value: "123" + staticPlacement: + locationLinks: + - {{APP_LOCATION_LINK}} diff --git a/spec/dummy/.controlplane/templates/gvc.yml b/spec/dummy/.controlplane/templates/gvc.yml new file mode 100644 index 00000000..95077ff6 --- /dev/null +++ b/spec/dummy/.controlplane/templates/gvc.yml @@ -0,0 +1,14 @@ +kind: gvc +name: {{APP_NAME}} +spec: + env: + - name: DATABASE_URL + value: postgres://postgres:password@postgres.{{APP_NAME}}.cpln.local:5432/{{APP_NAME}} + - name: SECRET_KEY_BASE + value: "123" + staticPlacement: + locationLinks: + - {{APP_LOCATION_LINK}} +--- +kind: identity +name: {{APP_IDENTITY}} diff --git a/spec/dummy/.controlplane/templates/invalid.yml b/spec/dummy/.controlplane/templates/invalid.yml new file mode 100644 index 00000000..40f50f0c --- /dev/null +++ b/spec/dummy/.controlplane/templates/invalid.yml @@ -0,0 +1,26 @@ +kind: workload +name: invalid +spec: + type: standard + containers: + - name: rails + cpu: 1m + memory: 1Mi + inheritEnv: true + image: {{APP_IMAGE_LINK}} + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 + outboundAllowCIDR: + - 0.0.0.0/0 + identityLink: {{APP_IDENTITY_LINK}} diff --git a/spec/dummy/.controlplane/templates/maintenance-with-external-image.yml b/spec/dummy/.controlplane/templates/maintenance-with-external-image.yml new file mode 100644 index 00000000..d296c8cf --- /dev/null +++ b/spec/dummy/.controlplane/templates/maintenance-with-external-image.yml @@ -0,0 +1,25 @@ +kind: workload +name: maintenance-with-external-image +spec: + type: standard + containers: + - name: maintenance + env: + - name: PORT + value: "3000" + - name: PAGE_URL + value: "https://hichee.com/maintenance.html" + image: external-image + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 diff --git a/spec/dummy/.controlplane/templates/maintenance.yml b/spec/dummy/.controlplane/templates/maintenance.yml new file mode 100644 index 00000000..9e4a2cda --- /dev/null +++ b/spec/dummy/.controlplane/templates/maintenance.yml @@ -0,0 +1,25 @@ +kind: workload +name: maintenance +spec: + type: standard + containers: + - name: maintenance + env: + - name: PORT + value: "3000" + - name: PAGE_URL + value: "https://hichee.com/maintenance.html" + image: "shakacode/maintenance-mode" + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 diff --git a/spec/dummy/.controlplane/templates/postgres-with-volume.yml b/spec/dummy/.controlplane/templates/postgres-with-volume.yml new file mode 100644 index 00000000..dc9f5789 --- /dev/null +++ b/spec/dummy/.controlplane/templates/postgres-with-volume.yml @@ -0,0 +1,41 @@ +# Based on https://github.com/controlplane-com/examples/blob/main/examples/postgres + +kind: volumeset +name: postgres-volume +spec: + fileSystemType: ext4 + performanceClass: general-purpose-ssd + initialCapacity: 10 +--- +kind: workload +name: postgres +spec: + type: stateful + containers: + - name: postgres + cpu: 50m + memory: 256Mi + env: + - name: PGDATA + value: /var/lib/postgresql/data/pg_data + - name: POSTGRES_USER + value: postgres + - name: POSTGRES_PASSWORD + value: password + image: postgres:15-alpine + ports: + - number: 5432 + protocol: tcp + volumes: + - path: /var/lib/postgresql/data + uri: cpln://volumeset/postgres-volume + recoveryPolicy: retain + defaultOptions: + autoscaling: + metric: latency + minScale: 1 + maxScale: 1 + capacityAI: false + firewallConfig: + internal: + inboundAllowType: same-gvc diff --git a/spec/dummy/.controlplane/templates/postgres.yml b/spec/dummy/.controlplane/templates/postgres.yml new file mode 100644 index 00000000..943a5596 --- /dev/null +++ b/spec/dummy/.controlplane/templates/postgres.yml @@ -0,0 +1,34 @@ +# Based on https://github.com/controlplane-com/examples/blob/main/examples/postgres + +kind: workload +name: postgres +spec: + type: standard + containers: + - name: postgres + cpu: 50m + memory: 256Mi + env: + - name: PGDATA + value: /var/lib/postgresql/data/pg_data + - name: POSTGRES_USER + value: postgres + - name: POSTGRES_PASSWORD + value: password + image: postgres:15-alpine + ports: + - number: 5432 + protocol: tcp + volumes: + - path: /var/lib/postgresql/data + uri: scratch://postgres-volume + recoveryPolicy: retain + defaultOptions: + autoscaling: + metric: latency + minScale: 1 + maxScale: 1 + capacityAI: false + firewallConfig: + internal: + inboundAllowType: same-gvc diff --git a/spec/dummy/.controlplane/templates/rails-with-non-app-image.yml b/spec/dummy/.controlplane/templates/rails-with-non-app-image.yml new file mode 100644 index 00000000..a95d8e47 --- /dev/null +++ b/spec/dummy/.controlplane/templates/rails-with-non-app-image.yml @@ -0,0 +1,26 @@ +kind: workload +name: rails-with-non-app-image +spec: + type: standard + containers: + - name: rails + cpu: 512m + memory: 1Gi + inheritEnv: true + image: ruby:3.1.2-slim + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 + outboundAllowCIDR: + - 0.0.0.0/0 + identityLink: {{APP_IDENTITY_LINK}} diff --git a/spec/dummy/.controlplane/templates/rails.yml b/spec/dummy/.controlplane/templates/rails.yml new file mode 100644 index 00000000..826d825c --- /dev/null +++ b/spec/dummy/.controlplane/templates/rails.yml @@ -0,0 +1,26 @@ +kind: workload +name: rails +spec: + type: standard + containers: + - name: rails + cpu: 512m + memory: 1Gi + inheritEnv: true + image: {{APP_IMAGE_LINK}} + ports: + - number: 3000 + protocol: http + defaultOptions: + autoscaling: + minScale: 1 + maxScale: 1 + capacityAI: false + timeoutSeconds: 60 + firewallConfig: + external: + inboundAllowCIDR: + - 0.0.0.0/0 + outboundAllowCIDR: + - 0.0.0.0/0 + identityLink: {{APP_IDENTITY_LINK}} diff --git a/spec/dummy/.controlplane/templates/secrets-policy.yml b/spec/dummy/.controlplane/templates/secrets-policy.yml new file mode 100644 index 00000000..9e85bac8 --- /dev/null +++ b/spec/dummy/.controlplane/templates/secrets-policy.yml @@ -0,0 +1,5 @@ +kind: policy +name: {{APP_SECRETS_POLICY}} +targetKind: secret +targetLinks: + - //secret/{{APP_SECRETS}} diff --git a/spec/dummy/bin/docker-entrypoint b/spec/dummy/bin/docker-entrypoint deleted file mode 100755 index 67ef4931..00000000 --- a/spec/dummy/bin/docker-entrypoint +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -e - -# If running the rails server then create or migrate existing database -if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then - ./bin/rails db:prepare -fi - -exec "${@}" diff --git a/spec/dummy/config/database.yml b/spec/dummy/config/database.yml index 85af94ee..8b9e432e 100644 --- a/spec/dummy/config/database.yml +++ b/spec/dummy/config/database.yml @@ -1,84 +1,20 @@ -# PostgreSQL. Versions 9.3 and up are supported. -# -# Install the pg driver: -# gem install pg -# On macOS with Homebrew: -# gem install pg -- --with-pg-config=/usr/local/bin/pg_config -# On Windows: -# gem install pg -# Choose the win32 build. -# Install PostgreSQL and put its /bin directory on your path. -# -# Configure Using Gemfile -# gem "pg" -# default: &default adapter: postgresql encoding: unicode - # For details on connection pooling, see Rails configuration guide - # https://guides.rubyonrails.org/configuring.html#database-pooling - pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + pool: <%= ENV["RAILS_MAX_THREADS"] || 5 %> + host: <%= ENV["DB_HOST"] || "localhost" %> + port: <%= ENV["DB_PORT"] || "5432" %> + username: <%= ENV["DB_USER"] || "postgres" %> + password: <%= ENV["DB_PASSWORD"] %> development: <<: *default database: dummy_development - # The specified database role being used to connect to PostgreSQL. - # To create additional roles in PostgreSQL see `$ createuser --help`. - # When left blank, PostgreSQL will use the default role. This is - # the same name as the operating system user running Rails. - #username: dummy - - # The password associated with the PostgreSQL role (username). - #password: - - # Connect on a TCP socket. Omitted by default since the client uses a - # domain socket that doesn't need configuration. Windows does not have - # domain sockets, so uncomment these lines. - #host: localhost - - # The TCP port the server listens on. Defaults to 5432. - # If your server runs on a different port number, change accordingly. - #port: 5432 - - # Schema search path. The server defaults to $user,public - #schema_search_path: myapp,sharedapp,public - - # Minimum log levels, in increasing order: - # debug5, debug4, debug3, debug2, debug1, - # log, notice, warning, error, fatal, and panic - # Defaults to warning. - #min_messages: notice - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. test: <<: *default database: dummy_test -# As with config/credentials.yml, you never want to store sensitive information, -# like your database password, in your source code. If your source code is -# ever seen by anyone, they now have access to your database. -# -# Instead, provide the password or a full connection URL as an environment -# variable when you boot the app. For example: -# -# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" -# -# If the connection URL is provided in the special DATABASE_URL environment -# variable, Rails will automatically merge its configuration values on top of -# the values provided in this file. Alternatively, you can specify a connection -# URL environment variable explicitly: -# -# production: -# url: <%= ENV["MY_APP_DATABASE_URL"] %> -# -# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database -# for a full overview on how database connection configuration can be specified. -# production: <<: *default database: dummy_production - username: dummy - password: <%= ENV["DUMMY_DATABASE_PASSWORD"] %> diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0939d17a..3e97db7e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,25 +1,34 @@ # frozen_string_literal: true +ENV["RAILS_ENV"] ||= "test" +ENV["HIDE_COMMAND_OUTPUT"] = "true" + +require "rspec/retry" require "simplecov" require "timecop" -require "vcr" SimpleCov.start do enable_coverage :branch -end -VCR.configure do |config| - config.cassette_library_dir = "spec/cassettes" - config.hook_into :webmock - config.configure_rspec_metadata! + enable_for_subprocesses true + at_fork do |pid| + # This needs a unique name so it won't be overwritten + command_name "#{SimpleCov.command_name} (subprocess: #{pid})" + + print_error_status false + formatter SimpleCov::Formatter::SimpleFormatter + minimum_coverage 0 - config.filter_sensitive_data("") do |interaction| - interaction.request.headers["Authorization"]&.first + start do + enable_coverage :branch + end end end require_relative "../lib/cpl" +require_relative "support/dummy_app_setup" require_relative "support/command_helpers" +require_relative "support/date_time_helpers" # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. @@ -118,9 +127,27 @@ # Kernel.srand config.seed config.include CommandHelpers + config.include DateTimeHelpers + + config.verbose_retry = true + config.display_try_failure_messages = true + config.default_retry_count = ENV["RSPEC_RETRY_COUNT"] || 3 + + config.before(:suite) do + DummyAppSetup.setup + end + + config.after(:suite) do + DummyAppSetup.cleanup unless ENV.fetch("SKIP_CLEANUP", nil) == "true" + end config.before do allow(Cpl::Cli).to receive(:check_cpln_version) allow(Cpl::Cli).to receive(:check_cpl_version) end + + config.around do |example| + # Times out after 10 minutes + Timeout.timeout(600) { example.run } + end end diff --git a/spec/support/command_helpers.rb b/spec/support/command_helpers.rb index f46c2941..27cdb441 100644 --- a/spec/support/command_helpers.rb +++ b/spec/support/command_helpers.rb @@ -1,17 +1,231 @@ # frozen_string_literal: true -module CommandHelpers - def command_output - tmp_stderr = Tempfile.create +require "securerandom" +require "pty" - allow_any_instance_of(Command::Base).to receive(:progress).and_return(tmp_stderr) # rubocop:disable RSpec/AnyInstance +require_relative "spawned_command" - yield +module CommandHelpers # rubocop:disable Metrics/ModuleLength + module_function - tmp_stderr.rewind - output = tmp_stderr.read - tmp_stderr.close + DUMMY_TEST_ORG = ENV.fetch("CPLN_ORG") + DUMMY_TEST_APP_PREFIX = "dummy-test" + LOG_FILE = ENV.fetch("SPEC_LOG_FILE", "spec.log") - output + CREATE_APP_PARAMS = { + "default" => { + deploy: false, + image_before_deploy_count: 0, + image_after_deploy_count: 0 + }, + "full" => { + deploy: true, + image_before_deploy_count: 2, + image_after_deploy_count: 0 + }, + "with-image-retention" => { + deploy: false, + image_before_deploy_count: 3, + image_after_deploy_count: 0 + }, + "with-rails-with-non-app-image" => { + deploy: false, + image_before_deploy_count: 1, + image_after_deploy_count: 0 + } + }.freeze + + COMMAND_SEPARATOR = "#" * 100 + SECTION_SEPARATOR = "-" * 100 + + def dummy_test_org + DUMMY_TEST_ORG + end + + # `extra_prefix` is used to differentiate between different dummy apps, + # e.g., "dummy-test-default", "dummy-test-with-nothing", etc. + # + # Returns the full prefix. + def dummy_test_app_prefix(extra_prefix = "") + prefix = DUMMY_TEST_APP_PREFIX + prefix += "-#{extra_prefix}" unless extra_prefix.nil? || extra_prefix.empty? + + prefix + end + + # `extra_prefix` is used to differentiate between different dummy apps, + # e.g., "dummy-test-default", "dummy-test-with-nothing", etc. + # + # `suffix` is used to differentiate between different dummy apps with the same `extra_prefix`, + # e.g., "dummy-test-default-1", "dummy-test-default-2", etc. + # If `suffix` is `nil` or empty, a random suffix is generated. + # + # If `create_if_not_exists` is `true`, the app is created if it doesn't exist, + # using the definition from `.controlplane/controlplane.yml` for the `extra_prefix`, + # and the corresponding params from `CREATE_APP_PARAMS`. + # No random suffix is generated in this case, since the app name must remain the same across multiple specs. + # + # Returns the app name. + def dummy_test_app(extra_prefix = "", suffix = "", create_if_not_exists: false) # rubocop:disable Metrics/CyclomaticComplexity + prefix = dummy_test_app_prefix(extra_prefix) + suffix = SecureRandom.hex(4) if (suffix.nil? || suffix.empty?) && !create_if_not_exists + + app = prefix + app += "-#{suffix}" unless suffix.nil? || suffix.empty? + return app unless create_if_not_exists + + params = CREATE_APP_PARAMS[extra_prefix] || CREATE_APP_PARAMS["default"] + create_app_if_not_exists(app, **params) + + app + end + + def apps_to_delete + @@apps_to_delete ||= [] # rubocop:disable Style/ClassVars + end + + def create_app_if_not_exists(app, deploy: false, image_before_deploy_count: 0, image_after_deploy_count: 0) # rubocop:disable Metrics/MethodLength + apps_to_delete.push(app) + + result = run_cpl_command("exists", "-a", app) + return app if result[:status].zero? + + puts "\nCreating app '#{app}' for tests\n\n" if ENV.fetch("VERBOSE_TESTS", nil) == "true" + + run_cpl_command!("setup-app", "-a", app, "--skip-secret-access-binding") + + image_before_deploy_count.times do + run_cpl_command!("build-image", "-a", app) + end + run_cpl_command!("deploy-image", "-a", app) if deploy + image_after_deploy_count.times do + run_cpl_command!("build-image", "-a", app) + end + + app + end + + def run_cpl_command(*args, raise_errors: false) # rubocop:disable Metrics/MethodLength + write_command_to_log(args.join(" ")) + + result = { + status: 0, + stderr: "", + stdout: "" + } + + original_stderr = replace_stderr + original_stdout = replace_stdout + + begin + Cpl::Cli.start(args) + rescue SystemExit => e + result[:status] = e.status + end + + result[:stderr] = restore_stderr(original_stderr) + result[:stdout] = restore_stdout(original_stdout) + + write_command_result_to_log(result) + + raise result.to_json if result[:status].nonzero? && raise_errors + + result + end + + def run_cpl_command!(*args) + run_cpl_command(*args, raise_errors: true) + end + + def spawn_cpl_command(*args, stty_rows: nil, stty_cols: nil, wait_for_process: true) + cmd = "" + cmd += "stty rows #{stty_rows} && " if stty_rows + cmd += "stty cols #{stty_cols} && " if stty_cols + cmd += "#{cpl_executable_with_simplecov} #{args.join(' ')}" + + write_command_to_log(cmd) + + PTY.spawn(cmd) do |output, input, pid| + yield(SpawnedCommand.new(output, input, pid)) + ensure + Process.wait(pid) if wait_for_process + end + end + + def write_command_to_log(cmd) + File.open(LOG_FILE, "a") do |file| + file.puts(COMMAND_SEPARATOR) + file.puts(cmd) + end + end + + def write_command_result_to_log(result) # rubocop:disable Metrics/MethodLength + File.open(LOG_FILE, "a") do |file| + file.puts(SECTION_SEPARATOR) + file.puts("STATUS: #{result[:status]}") + file.puts(SECTION_SEPARATOR) + file.puts("STDERR:") + file.puts(SECTION_SEPARATOR) + file.puts(result[:stderr]) + file.puts(SECTION_SEPARATOR) + file.puts("STDOUT:") + file.puts(SECTION_SEPARATOR) + file.puts(result[:stdout]) + end + end + + def replace_stderr + original_stderr = $stderr + $stderr = Tempfile.create + + original_stderr + end + + def replace_stdout + original_stdout = $stdout + $stdout = Tempfile.create + + original_stdout + end + + def restore_stderr(original_stderr) + $stderr.rewind + contents = $stderr.read + $stderr.close + $stderr = original_stderr + + contents + end + + def restore_stdout(original_stdout) + $stdout.rewind + contents = $stdout.read + $stdout.close + $stdout = original_stdout + + contents + end + + def cpl_executable + File.join(root_directory, "cpl") + end + + def cpl_executable_with_simplecov + "ruby -r #{simplecov_spawn_file} #{cpl_executable}" + end + + def simplecov_spawn_file + File.join(root_directory, ".simplecov_spawn") + end + + def root_directory + File.dirname(spec_directory) + end + + def spec_directory + current_file_path = File.expand_path(__FILE__) + current_directory = File.dirname(current_file_path) + + File.dirname(current_directory) end end diff --git a/spec/support/date_time_helpers.rb b/spec/support/date_time_helpers.rb new file mode 100644 index 00000000..d0acceeb --- /dev/null +++ b/spec/support/date_time_helpers.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module DateTimeHelpers + module_function + + def travel_to_days_later(days) + current_date = Time.now + target_date = current_date + (days * 24 * 60 * 60) + + Timecop.freeze(target_date) + end + + def travel_back + Timecop.return + end +end diff --git a/spec/support/dummy_app_setup.rb b/spec/support/dummy_app_setup.rb new file mode 100644 index 00000000..796f0ecc --- /dev/null +++ b/spec/support/dummy_app_setup.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module DummyAppSetup + module_function + + def setup + ENV["CONFIG_FILE_PATH"] = "#{CommandHelpers.spec_directory}/dummy/.controlplane/controlplane.yml" + + puts "\nUsing org '#{CommandHelpers.dummy_test_org}' for tests with dummy app\n\n" + end + + def cleanup + if CommandHelpers.apps_to_delete.empty? + puts "\n\nNo dummy apps to delete\n" + return + end + + CommandHelpers.apps_to_delete.each do |app| + CommandHelpers.run_cpl_command("delete", "-a", app, "--yes") + end + end +end diff --git a/spec/support/spawned_command.rb b/spec/support/spawned_command.rb new file mode 100644 index 00000000..f710001d --- /dev/null +++ b/spec/support/spawned_command.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "expect" + +class SpawnedCommand + attr_reader :output, :input, :pid + + DEFAULT_TIMEOUT = 120 + + def initialize(output, input, pid) + @output = output + @input = input + @pid = pid + end + + def wait_for(regex, timeout: DEFAULT_TIMEOUT) + result = nil + output.expect(regex, timeout) do |matches| + result = matches&.first + end + + raise "Timed out waiting for #{regex.inspect} after #{timeout} seconds" if result.nil? + + result + end + + def wait_for_prompt + wait_for(/[$#>]/) + end + + def type(string) + input.puts("#{string}\n") + end + + def kill + Process.kill("INT", pid) + end +end