cpflow 3.0.1 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 305f8dddc321aed06da473ca199d7411a40ed8bf3498ba09b4f7d77b1fb2f554
4
- data.tar.gz: 9656d940052e40e1914a7930606022b5acc75483aa10b1fe144e4ed9a68ac4d9
3
+ metadata.gz: 48de117fc2fbc2458b8469bfb3d93663c2950777803f84079dfdfa7cdbcda9e9
4
+ data.tar.gz: e3a8347bd330f6df7d2d5e98a3692144fa04d3c935241fbacf7ab06c8f039e79
5
5
  SHA512:
6
- metadata.gz: 1a51e614265cbbc86f89251ed5a8a8804d9caabe316301c26d0d839c80713b583726fae91f2c24bb1b778caaff23e6156f027a9b051c892816fe788b1ead5e8a
7
- data.tar.gz: 75a834c607df1cefce11f509059c60ae6db790a2be7a9217cc054401f30b855be0a388e61ecce56413929ea2cd24a0b479ce3e474c964127e134f571cd816690
6
+ metadata.gz: '06907b1c67896b14b71376bc88253fcd74a675fb088aab8f6c7bf051ebfaf3f463c3ab96bf33bf64abe6da5bf1dff22529503508176a6d1fc5c35517021c9dc4'
7
+ data.tar.gz: ae76127106fa6dc3544669163e94571d68ec149f22b8ed68d1cf0332c3f333b65e1a1d2f6f6b2cb75039d45bcf1f8418f1cb4d5ceba750cf11cc930ac5d38ac4
@@ -3,19 +3,22 @@ name: RSpec Shared
3
3
  on:
4
4
  workflow_call:
5
5
  inputs:
6
- os-version:
6
+ os_version:
7
7
  required: true
8
8
  type: string
9
- ruby-version:
9
+ ruby_version:
10
10
  required: true
11
11
  type: string
12
- test-tag:
13
- required: true
12
+ test_tag:
13
+ required: false
14
+ type: string
15
+ spec_paths:
16
+ required: false
14
17
  type: string
15
18
 
16
19
  jobs:
17
20
  rspec:
18
- runs-on: ${{ inputs.os-version }}
21
+ runs-on: ${{ inputs.os_version }}
19
22
  env:
20
23
  RAILS_ENV: test
21
24
  # We have to add "_CI" to the end, otherwise it messes with tests where we switch profiles,
@@ -28,7 +31,7 @@ jobs:
28
31
  - name: Set up Ruby
29
32
  uses: ruby/setup-ruby@v1
30
33
  with:
31
- ruby-version: ${{ inputs.ruby-version }}
34
+ ruby-version: ${{ inputs.ruby_version }}
32
35
  bundler-cache: true
33
36
  - name: Install dependencies
34
37
  run: bundle install
@@ -41,16 +44,16 @@ jobs:
41
44
  cpln profile create default --token $CPLN_TOKEN_CI --org $CPLN_ORG
42
45
  cpln image docker-login
43
46
  - name: Run tests
44
- run: bundle exec rspec --format documentation --tag ${{ inputs.test-tag }}
47
+ run: bundle exec rspec --format documentation ${{ inputs.test_tag && format('--tag {0}', inputs.test_tag) }} ${{ inputs.spec_paths }}
45
48
  - name: Upload spec log
46
49
  uses: actions/upload-artifact@master
47
50
  if: always()
48
51
  with:
49
- name: spec-${{ inputs.test-tag }}-${{ github.run_id }}-${{ inputs.os-version }}-${{ inputs.ruby-version }}.log
52
+ name: spec-${{ inputs.test_tag }}-${{ github.run_id }}-${{ inputs.os_version }}-${{ inputs.ruby_version }}.log
50
53
  path: spec.log
51
54
  - name: Upload coverage results
52
55
  uses: actions/upload-artifact@master
53
56
  if: always()
54
57
  with:
55
- name: coverage-report-${{ inputs.test-tag }}-${{ github.run_id }}-${{ inputs.os-version }}-${{ inputs.ruby-version }}
58
+ name: coverage-report-${{ inputs.test_tag }}-${{ github.run_id }}-${{ inputs.os_version }}-${{ inputs.ruby_version }}
56
59
  path: coverage
@@ -0,0 +1,18 @@
1
+ name: RSpec Specific
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ spec_paths:
7
+ description: "Test files or directories that should be run"
8
+ required: true
9
+
10
+ jobs:
11
+ rspec-specific:
12
+ name: RSpec (Specific)
13
+ uses: ./.github/workflows/rspec-shared.yml
14
+ with:
15
+ os_version: ubuntu-latest
16
+ ruby_version: "3.2"
17
+ spec_paths: ${{ inputs.spec_paths }}
18
+ secrets: inherit
@@ -12,9 +12,9 @@ jobs:
12
12
  name: RSpec (Fast)
13
13
  uses: ./.github/workflows/rspec-shared.yml
14
14
  with:
15
- os-version: ubuntu-latest
16
- ruby-version: "3.2"
17
- test-tag: ~slow
15
+ os_version: ubuntu-latest
16
+ ruby_version: "3.2"
17
+ test_tag: ~slow
18
18
  secrets: inherit
19
19
 
20
20
  rspec-slow:
@@ -22,7 +22,7 @@ jobs:
22
22
  uses: ./.github/workflows/rspec-shared.yml
23
23
  if: github.event_name == 'workflow_dispatch'
24
24
  with:
25
- os-version: ubuntu-latest
26
- ruby-version: "3.2"
27
- test-tag: slow
25
+ os_version: ubuntu-latest
26
+ ruby_version: "3.2"
27
+ test_tag: slow
28
28
  secrets: inherit
data/.overcommit.yml CHANGED
@@ -10,7 +10,7 @@ PreCommit:
10
10
  on_warn: fail
11
11
  command: ["bundle", "exec", "rubocop"]
12
12
 
13
- PrePush:
14
- RSpec:
15
- enabled: true
16
- command: ["bundle", "exec", "rspec"]
13
+ # PrePush:
14
+ # RSpec:
15
+ # enabled: true
16
+ # command: ["bundle", "exec", "rspec"]
data/.rubocop.yml CHANGED
@@ -20,3 +20,7 @@ RSpec/ExampleLength:
20
20
 
21
21
  RSpec/MultipleExpectations:
22
22
  Enabled: false
23
+
24
+ RSpec/NestedGroups:
25
+ Enabled: true
26
+ Max: 5
data/CHANGELOG.md CHANGED
@@ -14,12 +14,34 @@ Changes since the last non-beta release.
14
14
 
15
15
  _Please add entries here for your pull requests that have not yet been released._
16
16
 
17
+ ### Fixed
18
+
19
+ - Fixed issue where `run` command fails when runner workload has ENV but original workload does not. [PR 227](https://github.com/shakacode/control-plane-flow/pull/227) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
20
+
21
+ - Fixed potential infinite loop that could occur for a command if one of the execution steps fails and gets stuck. [PR 217](https://github.com/shakacode/control-plane-flow/pull/217) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
22
+
23
+ ## [4.0.0] - 2024-08-21
24
+
25
+ ### Fixed
26
+
27
+ - Fixed issue where common options are not forwarded to other commands. [PR 207](https://github.com/shakacode/control-plane-flow/pull/207) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
28
+ - Fixed BYOK endpoint. [PR 209](https://github.com/shakacode/control-plane-flow/pull/209) by [Sergey Tarasov](https://github.com/dzirtusss).
29
+ - Fixed issue where `generate` command fails if no project config exists. [PR 219](https://github.com/shakacode/control-plane-flow/pull/219) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
30
+ - Bumped min `cpln` version to `3.1.0` and fixed `cpln workload exec` calls. [PR 226](https://github.com/shakacode/control-plane-flow/pull/226) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
31
+
32
+ ## [3.0.1] - 2024-06-26
33
+
34
+ ### Fixed
35
+
36
+ - Moved development dependencies to Gemfile and updated many of them. [PR 208](https://github.com/shakacode/control-plane-flow/pull/208) by [Justin Gordon](https://github.com/justin808).
37
+
38
+ ## [3.0.0] - 2024-06-21
17
39
 
18
- ## [3.0.0] - 2024-06-20
19
40
  First release of `cpflow`.
20
41
 
21
- ## [2.2.4] - 2024-06-20
22
- Deprecate `cpl` CLI. New gem is `cpflow`
42
+ ## [2.2.4] - 2024-06-21
43
+
44
+ Deprecated `cpl` gem. New gem is `cpflow`.
23
45
 
24
46
  ## [2.2.1] - 2024-06-17
25
47
 
@@ -64,17 +86,17 @@ Deprecate `cpl` CLI. New gem is `cpflow`
64
86
  - Specific validations are now run before commands, and the command will exit with a non-zero code if any validation fails. Can be disabled by setting `DISABLE_VALIDATIONS` env var to `true`. [PR 185](https://github.com/shakacode/control-plane-flow/pull/185) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
65
87
  - Deprecated the `--skip-secret-access-binding` option in favor of `--skip-secrets-setup`. This can also now be configured through `skip_secrets_setup` in `controlplane.yml` [PR 190](https://github.com/shakacode/control-plane-flow/pull/190) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
66
88
 
67
- ## [2.0.2] - 2024-05-17
89
+ ## [2.0.2] - 2024-05-18
68
90
 
69
91
  - Fixed issue with improper handling of job statuses. Fixed issue with interactive magic string showing and exit code. [PR 177](https://github.com/shakacode/control-plane-flow/pull/177) by [Sergey Tarasov](https://github.com/dzirtusss).
70
92
 
71
- ## [2.0.1] - 2024-05-15
93
+ ## [2.0.1] - 2024-05-16
72
94
 
73
95
  ### Fixed
74
96
 
75
97
  - Fixed issue where `cleanup-stale-apps` command fails to delete apps with volumesets. [PR 175](https://github.com/shakacode/control-plane-flow/pull/175) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
76
98
 
77
- ## [2.0.0] - 2024-05-14
99
+ ## [2.0.0] - 2024-05-15
78
100
 
79
101
  ### BREAKING CHANGES
80
102
 
@@ -104,7 +126,7 @@ Deprecate `cpl` CLI. New gem is `cpflow`
104
126
  - `deploy-image` command now raises an error if image does not exist. [PR 153](https://github.com/shakacode/control-plane-flow/pull/153) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
105
127
  - `delete` command now unbinds identity from policy (if bound) when deleting app. [PR 170](https://github.com/shakacode/control-plane-flow/pull/170) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
106
128
 
107
- ## [1.4.0] - 2024-03-20
129
+ ## [1.4.0] - 2024-03-21
108
130
 
109
131
  ### Added
110
132
 
@@ -141,12 +163,12 @@ Deprecate `cpl` CLI. New gem is `cpflow`
141
163
  - `info` command now lists workloads in the same order as `controlplane.yml`. [PR 139](https://github.com/shakacode/control-plane-flow/pull/139) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
142
164
  - Improved domain workload matching for `maintenance`, `maintenance:on` and `maintenance:off` commands (instead of matching only by workload, it now matches by org + app + workload, which is more accurate). [PR 140](https://github.com/shakacode/control-plane-flow/pull/140) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
143
165
 
144
- ## [1.2.0] - 2024-01-03
166
+ ## [1.2.0] - 2024-01-04
145
167
 
146
168
  ### Fixed
147
169
 
148
170
  - Fixed issue where `info` command does not respect `CPLN_ORG` env var. [PR 88](https://github.com/shakacode/control-plane-flow/pull/88) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
149
- - Fixed issues with running `cpflow --version` and `cpflow --help` where no configuration file exists. [PR 100](https://github.com/shakacode/control-plane-flow/pull/100) by [Mostafa Ahangarha](https://github.com/ahangarha).
171
+ - Fixed issues with running `cpflow --version` and `cpflow --help` where no configuration file exists. [PR 109](https://github.com/shakacode/control-plane-flow/pull/109) by [Mostafa Ahangarha](https://github.com/ahangarha).
150
172
  - Fixed issue where `delete` command fails to delete apps with volumesets. [PR 123](https://github.com/shakacode/control-plane-flow/pull/123) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
151
173
 
152
174
  ### Added
@@ -157,19 +179,19 @@ Deprecate `cpl` CLI. New gem is `cpflow`
157
179
  - Added option to only use `CPLN_ORG` and `CPLN_APP` env vars if `allow_org_override_by_env` and `allow_app_override_by_env` configs are set to `true` in `controlplane.yml`. [PR 109](https://github.com/shakacode/control-plane-flow/pull/109) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
158
180
  - Added `CPLN_LOCATION` env variable and `--location` option for `apply-template`, `ps`, `run`, `run:detached`. [PR 105](https://github.com/shakacode/control-plane-flow/pull/105) by [Mostafa Ahangarha](https://github.com/ahangarha).
159
181
  - Added `generate` command for creating basic Control Plane configuration directory. [PR 116](https://github.com/shakacode/control-plane-flow/pull/116) by [Mostafa Ahangarhga](https://github.com/ahangarha).
160
- - Added `--trace` option to all commands for more detailed logs. [PR 124](https://github.com/shakacode/control-plane-flow/pull/124) by [justin808](https://github.com/justin808)
161
- - Added better error message to check the org name in case of a 403 error. [PR 124](https://github.com/justin808) by [justin808](https://github.com/justin808)
182
+ - Added `--trace` option to all commands for more detailed logs. [PR 124](https://github.com/shakacode/control-plane-flow/pull/124) by [Justin Gordon](https://github.com/justin808).
183
+ - Added better error message to check the org name in case of a 403 error. [PR 124](https://github.com/shakacode/control-plane-flow/pull/124) by [Justin Gordon](https://github.com/justin808).
162
184
 
163
185
  ### Changed
164
186
 
165
187
  - `--org` option now takes precedence over `CPLN_ORG` env var, which takes precedence over `cpln_org` from `controlplane.yml`. [PR 88](https://github.com/shakacode/control-plane-flow/pull/88) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
166
188
  - Renamed `setup` config into `setup_app_templates`. [PR 112](https://github.com/shakacode/control-plane-flow/pull/112) by [Mostafa Ahangarha](https://github.com/ahangarha).
167
189
 
168
- ## [1.1.2] - 2023-10-17
190
+ ## [1.1.2] - 2023-10-25
169
191
 
170
192
  ### Fixed
171
193
 
172
- - Fixed failed build on MacOS by adding platform flag and fixed multiple files in yaml document for template. [PR 81](https://github.com/shakacode/control-plane-flow/pull/81) by [justin808](https://github.com/justin808).
194
+ - Fixed failed build on MacOS by adding platform flag and fixed multiple files in yaml document for template. [PR 81](https://github.com/shakacode/control-plane-flow/pull/81) by [Justin Gordon](https://github.com/justin808).
173
195
 
174
196
  ### Added
175
197
 
@@ -181,7 +203,7 @@ Deprecate `cpl` CLI. New gem is `cpflow`
181
203
 
182
204
  - Calling `cpflow` with no command now shows the help menu. [PR 83](https://github.com/shakacode/control-plane-flow/pull/83) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
183
205
 
184
- ## [1.1.1] - 2023-09-23
206
+ ## [1.1.1] - 2023-09-21
185
207
 
186
208
  ### Fixed
187
209
 
@@ -205,7 +227,7 @@ Deprecate `cpl` CLI. New gem is `cpflow`
205
227
  - Renamed `cleanup-old-images` command to `cleanup-images`. [PR 72](https://github.com/shakacode/control-plane-flow/pull/72) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
206
228
  - Renamed `old_image_retention_days` config to `image_retention_days`. [PR 72](https://github.com/shakacode/control-plane-flow/pull/72) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
207
229
 
208
- ## [1.0.4] - 2023-07-21
230
+ ## [1.0.4] - 2023-07-24
209
231
 
210
232
  ### Fixed
211
233
 
@@ -244,9 +266,11 @@ Deprecate `cpl` CLI. New gem is `cpflow`
244
266
 
245
267
  ## [1.0.0] - 2023-05-29
246
268
 
247
- - Initial release
269
+ First release.
248
270
 
249
- [Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v3.0.0...HEAD
271
+ [Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v4.0.0...HEAD
272
+ [4.0.0]: https://github.com/shakacode/control-plane-flow/compare/v3.0.1...v4.0.0
273
+ [3.0.1]: https://github.com/shakacode/control-plane-flow/compare/v3.0.0...v3.0.1
250
274
  [3.0.0]: https://github.com/shakacode/control-plane-flow/compare/v2.2.4...v3.0.0
251
275
  [2.2.4]: https://github.com/shakacode/control-plane-flow/compare/v2.2.1...v2.2.4
252
276
  [2.2.1]: https://github.com/shakacode/control-plane-flow/compare/v2.2.0...v2.2.1
data/CONTRIBUTING.md CHANGED
@@ -64,7 +64,7 @@ CPLN_ORG=your-org-for-tests bundle exec rspec --tag slow
64
64
  2. Use the `--trace` option to see full logging of HTTP requests. Warning, this will display keys to your logs or console.
65
65
  1. Add a breakpoint (`debugger`) to any line of code you want to debug.
66
66
  2. Modify the `lib/command/test.rb` file to trigger the code you want to test. To simulate a command, you can use
67
- `Cpflow::Cli.start` (e.g., `Cpflow::Cli.start(["deploy-image", "-a", "my-app-name"])` would be the same as running
67
+ `run_cpflow_command` (e.g., `run_cpflow_command("deploy-image", "-a", "my-app-name")` would be the same as running
68
68
  `cpflow deploy-image -a my-app-name`).
69
69
  3. Run the `test` command in your test app with a `.controlplane` directory.
70
70
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpflow (3.0.1)
4
+ cpflow (4.0.1)
5
5
  dotenv (~> 2.8.1)
6
6
  jwt (~> 2.8.1)
7
7
  psych (~> 5.1.0)
@@ -43,7 +43,7 @@ module Command
43
43
  VALIDATIONS = %w[config templates].freeze
44
44
 
45
45
  def call # rubocop:disable Metrics/MethodLength
46
- @template_parser = TemplateParser.new(config)
46
+ @template_parser = TemplateParser.new(self)
47
47
  @names_to_filenames = config.args.to_h do |name|
48
48
  [name, @template_parser.template_filename(name)]
49
49
  end
data/lib/command/base.rb CHANGED
@@ -465,45 +465,50 @@ module Command
465
465
  $stderr
466
466
  end
467
467
 
468
- def step_error(error, abort_on_error: true)
469
- message = error.message
470
- if abort_on_error
471
- progress.puts(" #{Shell.color('failed!', :red)}\n\n")
472
- Shell.abort(message)
473
- else
474
- Shell.write_to_tmp_stderr(message)
475
- end
476
- end
477
-
478
- def step_finish(success)
468
+ def step_finish(success, abort_on_error: true)
479
469
  if success
480
470
  progress.puts(" #{Shell.color('done!', :green)}")
481
471
  else
482
472
  progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
473
+ exit(ExitCode::ERROR_DEFAULT) if abort_on_error
483
474
  end
484
475
  end
485
476
 
486
- def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disable Metrics/MethodLength
477
+ def step(message, abort_on_error: true, retry_on_failure: false, max_retry_count: 1000, wait: 1, &block) # rubocop:disable Metrics/MethodLength
487
478
  progress.print("#{message}...")
488
479
 
489
480
  Shell.use_tmp_stderr do
490
481
  success = false
491
482
 
492
483
  begin
493
- if retry_on_failure
494
- until (success = yield)
495
- progress.print(".")
496
- Kernel.sleep(1)
484
+ success =
485
+ if retry_on_failure
486
+ with_retry(max_retry_count: max_retry_count, wait: wait, &block)
487
+ else
488
+ yield
497
489
  end
498
- else
499
- success = yield
500
- end
501
490
  rescue RuntimeError => e
502
- step_error(e, abort_on_error: abort_on_error)
491
+ Shell.write_to_tmp_stderr(e.message)
503
492
  end
504
493
 
505
- step_finish(success)
494
+ step_finish(success, abort_on_error: abort_on_error)
495
+ end
496
+ end
497
+
498
+ def with_retry(max_retry_count:, wait:)
499
+ retry_count = 0
500
+ success = false
501
+
502
+ while !success && retry_count <= max_retry_count
503
+ success = yield
504
+ break if success
505
+
506
+ progress.print(".")
507
+ Kernel.sleep(wait)
508
+ retry_count += 1
506
509
  end
510
+
511
+ success
507
512
  end
508
513
 
509
514
  def cp
@@ -527,7 +532,7 @@ module Command
527
532
  progress.puts("Running #{title}...\n\n")
528
533
 
529
534
  begin
530
- Cpflow::Cli.start(["run", "-a", config.app, "--image", "latest", "--", command])
535
+ run_cpflow_command("run", "-a", config.app, "--image", "latest", "--", command)
531
536
  rescue SystemExit => e
532
537
  progress.puts
533
538
 
@@ -536,5 +541,19 @@ module Command
536
541
  progress.puts("Finished running #{title}.\n\n")
537
542
  end
538
543
  end
544
+
545
+ def run_cpflow_command(command, *args)
546
+ common_args = []
547
+
548
+ self.class.common_options.each do |option|
549
+ value = config.options[option[:name]]
550
+ next if value.nil?
551
+
552
+ name = "--#{option[:name].to_s.tr('_', '-')}"
553
+ common_args.push(name, value)
554
+ end
555
+
556
+ Cpflow::Cli.start([command, *common_args, *args])
557
+ end
539
558
  end
540
559
  end
@@ -38,7 +38,11 @@ module Command
38
38
  docker_args: config.args,
39
39
  build_args: build_args)
40
40
 
41
- progress.puts("\nPushed image to '/org/#{config.org}/image/#{image_name}'.\n\n")
41
+ push_path = "/org/#{config.org}/image/#{image_name}"
42
+
43
+ progress.puts("\nPushing image to '#{push_path}'...\n\n")
44
+ cp.image_push(image_url)
45
+ progress.puts("\nPushed image to '#{push_path}'.\n\n")
42
46
 
43
47
  step("Waiting for image to be available", retry_on_failure: true) do
44
48
  images = cp.query_images["items"]
@@ -73,7 +73,7 @@ module Command
73
73
  end
74
74
 
75
75
  def delete_app(app)
76
- Cpflow::Cli.start(["delete", "-a", app, "--yes"])
76
+ run_cpflow_command("delete", "-a", app, "--yes")
77
77
  end
78
78
  end
79
79
  end
@@ -35,7 +35,7 @@ module Command
35
35
  container_name = container["name"]
36
36
  step("Deploying image '#{image}' for workload '#{container_name}'") do
37
37
  cp.workload_set_image_ref(workload, container: container_name, image: image)
38
- deployed_endpoints[container_name] = workload_data.dig("status", "endpoint")
38
+ deployed_endpoints[container_name] = endpoint_for_workload(workload_data)
39
39
  end
40
40
  end
41
41
  end
@@ -48,6 +48,15 @@ module Command
48
48
 
49
49
  private
50
50
 
51
+ def endpoint_for_workload(workload_data)
52
+ endpoint = workload_data.dig("status", "endpoint")
53
+ Resolv.getaddress(endpoint.split("/").last)
54
+ endpoint
55
+ rescue Resolv::ResolvError
56
+ deployments = cp.fetch_workload_deployments(workload_data["name"])
57
+ deployments.dig("items", 0, "status", "endpoint")
58
+ end
59
+
51
60
  def run_release_script
52
61
  release_script = config[:release_script]
53
62
  run_command_in_latest_image(release_script, title: "release script")
@@ -29,7 +29,7 @@ module Command
29
29
  validations = config.options[:validations].split(",")
30
30
  ensure_required_options!(validations)
31
31
 
32
- doctor_service = DoctorService.new(config)
32
+ doctor_service = DoctorService.new(self)
33
33
  doctor_service.run_validations(validations)
34
34
  end
35
35
 
@@ -26,6 +26,7 @@ module Command
26
26
  ```
27
27
  EX
28
28
  WITH_INFO_HEADER = false
29
+ VALIDATIONS = [].freeze
29
30
 
30
31
  def call
31
32
  if controlplane_directory_exists?
@@ -17,26 +17,14 @@ module Command
17
17
  DESC
18
18
  WITH_INFO_HEADER = false
19
19
 
20
- def call # rubocop:disable Metrics/MethodLength
21
- one_off_workload = config[:one_off_workload]
22
- maintenance_workload = config.current[:maintenance_workload] || "maintenance"
20
+ def call
21
+ puts maintenance_mode.enabled? ? "on" : "off"
22
+ end
23
23
 
24
- domain_data = if config.domain
25
- cp.fetch_domain(config.domain)
26
- else
27
- cp.find_domain_for([one_off_workload, maintenance_workload])
28
- end
29
- unless domain_data
30
- raise "Can't find domain. " \
31
- "Maintenance mode is only supported for domains that use path based routing mode " \
32
- "and have a route configured for the prefix '/' on either port 80 or 443."
33
- end
24
+ private
34
25
 
35
- if cp.domain_workload_matches?(domain_data, maintenance_workload)
36
- puts "on"
37
- else
38
- puts "off"
39
- end
26
+ def maintenance_mode
27
+ @maintenance_mode ||= MaintenanceMode.new(self)
40
28
  end
41
29
  end
42
30
  end
@@ -15,48 +15,14 @@ module Command
15
15
  - 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
16
16
  DESC
17
17
 
18
- def call # rubocop:disable Metrics/MethodLength
19
- one_off_workload = config[:one_off_workload]
20
- maintenance_workload = config.current[:maintenance_workload] || "maintenance"
21
-
22
- domain_data = if config.domain
23
- cp.fetch_domain(config.domain)
24
- else
25
- cp.find_domain_for([one_off_workload, maintenance_workload])
26
- end
27
- unless domain_data
28
- raise "Can't find domain. " \
29
- "Maintenance mode is only supported for domains that use path based routing mode " \
30
- "and have a route configured for the prefix '/' on either port 80 or 443."
31
- end
32
-
33
- domain = domain_data["name"]
34
- if cp.domain_workload_matches?(domain_data, one_off_workload)
35
- progress.puts("Maintenance mode is already disabled for app '#{config.app}'.")
36
- return
37
- end
38
-
39
- cp.fetch_workload!(maintenance_workload)
40
-
41
- # Start all other workloads
42
- Cpflow::Cli.start(["ps:start", "-a", config.app, "--wait"])
43
-
44
- progress.puts
45
-
46
- # Switch domain workload
47
- step("Switching workload for domain '#{domain}' to '#{one_off_workload}'") do
48
- cp.set_domain_workload(domain_data, one_off_workload)
49
-
50
- # Give it a bit of time for the domain to update
51
- Kernel.sleep(30)
52
- end
53
-
54
- progress.puts
18
+ def call
19
+ maintenance_mode.disable!
20
+ end
55
21
 
56
- # Stop maintenance workload
57
- Cpflow::Cli.start(["ps:stop", "-a", config.app, "-w", maintenance_workload, "--wait"])
22
+ private
58
23
 
59
- progress.puts("\nMaintenance mode disabled for app '#{config.app}'.")
24
+ def maintenance_mode
25
+ @maintenance_mode ||= MaintenanceMode.new(self)
60
26
  end
61
27
  end
62
28
  end
@@ -15,48 +15,14 @@ module Command
15
15
  - 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
16
16
  DESC
17
17
 
18
- def call # rubocop:disable Metrics/MethodLength
19
- one_off_workload = config[:one_off_workload]
20
- maintenance_workload = config.current[:maintenance_workload] || "maintenance"
21
-
22
- domain_data = if config.domain
23
- cp.fetch_domain(config.domain)
24
- else
25
- cp.find_domain_for([one_off_workload, maintenance_workload])
26
- end
27
- unless domain_data
28
- raise "Can't find domain. " \
29
- "Maintenance mode is only supported for domains that use path based routing mode " \
30
- "and have a route configured for the prefix '/' on either port 80 or 443."
31
- end
32
-
33
- domain = domain_data["name"]
34
- if cp.domain_workload_matches?(domain_data, maintenance_workload)
35
- progress.puts("Maintenance mode is already enabled for app '#{config.app}'.")
36
- return
37
- end
38
-
39
- cp.fetch_workload!(maintenance_workload)
40
-
41
- # Start maintenance workload
42
- Cpflow::Cli.start(["ps:start", "-a", config.app, "-w", maintenance_workload, "--wait"])
43
-
44
- progress.puts
45
-
46
- # Switch domain workload
47
- step("Switching workload for domain '#{domain}' to '#{maintenance_workload}'") do
48
- cp.set_domain_workload(domain_data, maintenance_workload)
49
-
50
- # Give it a bit of time for the domain to update
51
- Kernel.sleep(30)
52
- end
53
-
54
- progress.puts
18
+ def call
19
+ maintenance_mode.enable!
20
+ end
55
21
 
56
- # Stop all other workloads
57
- Cpflow::Cli.start(["ps:stop", "-a", config.app, "--wait"])
22
+ private
58
23
 
59
- progress.puts("\nMaintenance mode enabled for app '#{config.app}'.")
24
+ def maintenance_mode
25
+ @maintenance_mode ||= MaintenanceMode.new(self)
60
26
  end
61
27
  end
62
28
  end
@@ -14,9 +14,9 @@ module Command
14
14
 
15
15
  def call
16
16
  if config.options[:version]
17
- Cpflow::Cli.start(["version"])
17
+ run_cpflow_command("version")
18
18
  else
19
- Cpflow::Cli.start(["help"])
19
+ run_cpflow_command("help")
20
20
  end
21
21
  end
22
22
  end
@@ -25,14 +25,14 @@ module Command
25
25
  private
26
26
 
27
27
  def copy_image_from_upstream
28
- Cpflow::Cli.start(["copy-image-from-upstream", "-a", config.app, "-t", config.options[:upstream_token]])
28
+ run_cpflow_command("copy-image-from-upstream", "-a", config.app, "-t", config.options[:upstream_token])
29
29
  progress.puts
30
30
  end
31
31
 
32
32
  def deploy_image
33
33
  args = []
34
34
  args.push("--run-release-phase") if config.current[:release_script]
35
- Cpflow::Cli.start(["deploy-image", "-a", config.app, *args])
35
+ run_cpflow_command("deploy-image", "-a", config.app, *args)
36
36
  end
37
37
  end
38
38
  end
data/lib/command/run.rb CHANGED
@@ -207,7 +207,7 @@ module Command
207
207
  original_env_str = original_container_spec["env"]&.sort_by { |env| env["name"] }.to_s
208
208
  env_str = container_spec["env"]&.sort_by { |env| env["name"] }.to_s
209
209
  if original_env_str != env_str
210
- container_spec["env"] = original_container_spec["env"]
210
+ container_spec["env"] = original_container_spec["env"] || []
211
211
  should_update = true
212
212
  end
213
213
 
@@ -243,7 +243,7 @@ module Command
243
243
 
244
244
  step("Updating runner workload '#{runner_workload}'") do
245
245
  # Update runner workload
246
- @expected_deployed_version = cp.cron_workload_deployed_version(runner_workload) + 1
246
+ @expected_deployed_version = (cp.cron_workload_deployed_version(runner_workload) || 0) + 1
247
247
  cp.apply_hash("kind" => "workload", "name" => runner_workload, "spec" => spec)
248
248
  end
249
249
  end
@@ -256,7 +256,7 @@ module Command
256
256
 
257
257
  def wait_for_runner_workload_update
258
258
  step("Waiting for runner workload '#{runner_workload}' to be updated", retry_on_failure: true) do
259
- cp.cron_workload_deployed_version(runner_workload) >= expected_deployed_version
259
+ (cp.cron_workload_deployed_version(runner_workload) || 0) >= expected_deployed_version
260
260
  end
261
261
  end
262
262
 
@@ -306,7 +306,7 @@ module Command
306
306
  exit(ExitCode::SUCCESS)
307
307
  end
308
308
 
309
- Cpflow::Cli.start(["logs", *app_workload_replica_args])
309
+ run_cpflow_command("logs", *app_workload_replica_args)
310
310
  end
311
311
  Process.detach(logs_pid)
312
312
 
@@ -42,7 +42,7 @@ module Command
42
42
 
43
43
  args = []
44
44
  args.push("--add-app-identity") unless skip_secrets_setup
45
- Cpflow::Cli.start(["apply-template", *templates, "-a", config.app, *args])
45
+ run_cpflow_command("apply-template", *templates, "-a", config.app, *args)
46
46
 
47
47
  bind_identity_to_policy unless skip_secrets_setup
48
48
  run_post_creation_hook unless config.options[:skip_post_creation_hook]
data/lib/command/test.rb CHANGED
@@ -16,8 +16,8 @@ module Command
16
16
  def call
17
17
  # Modify this method to trigger the code you want to test.
18
18
  # You can use `debugger` to debug.
19
- # You can use `Cpflow::Cli.start` to simulate a command
20
- # (e.g., `Cpflow::Cli.start(["deploy-image", "-a", "my-app-name"])`).
19
+ # You can use `run_cpflow_command` to simulate a command
20
+ # (e.g., `run_cpflow_command("deploy-image", "-a", "my-app-name")`).
21
21
  end
22
22
  end
23
23
  end
@@ -90,7 +90,7 @@ class Controlplane # rubocop:disable Metrics/ClassLength
90
90
  api.query_images(org: a_org, gvc: a_gvc, gvc_op_type: gvc_op)
91
91
  end
92
92
 
93
- def image_build(image, dockerfile:, docker_args: [], build_args: [], push: true)
93
+ def image_build(image, dockerfile:, docker_args: [], build_args: [])
94
94
  # https://docs.controlplane.com/guides/push-image#step-2
95
95
  # Might need to use `docker buildx build` if compatiblitity issues arise
96
96
  cmd = "docker build --platform=linux/amd64 -t #{image} -f #{dockerfile}"
@@ -99,9 +99,8 @@ class Controlplane # rubocop:disable Metrics/ClassLength
99
99
  cmd += " #{docker_args.join(' ')}" if docker_args.any?
100
100
  build_args.each { |build_arg| cmd += " --build-arg #{build_arg}" }
101
101
  cmd += " #{config.app_dir}"
102
- perform!(cmd)
103
102
 
104
- image_push(image) if push
103
+ perform!(cmd)
105
104
  end
106
105
 
107
106
  def fetch_image_details(image)
@@ -278,7 +277,7 @@ class Controlplane # rubocop:disable Metrics/ClassLength
278
277
  end
279
278
 
280
279
  def workload_exec(workload, replica, location:, container: nil, command: nil)
281
- cmd = "cpln workload exec #{workload} #{gvc_org} --replica #{replica} --location #{location}"
280
+ cmd = "cpln workload exec #{workload} #{gvc_org} --replica #{replica} --location #{location} -it"
282
281
  cmd += " --container #{container}" if container
283
282
  cmd += " -- #{command}"
284
283
  perform!(cmd, output_mode: :all)
@@ -3,10 +3,12 @@
3
3
  class ValidationError < StandardError; end
4
4
 
5
5
  class DoctorService
6
- attr_reader :config
6
+ extend Forwardable
7
7
 
8
- def initialize(config)
9
- @config = config
8
+ def_delegators :@command, :config, :progress
9
+
10
+ def initialize(command)
11
+ @command = command
10
12
  end
11
13
 
12
14
  def run_validations(validations, silent_if_passing: false) # rubocop:disable Metrics/MethodLength
@@ -37,7 +39,7 @@ class DoctorService
37
39
  end
38
40
 
39
41
  def validate_templates
40
- @template_parser = TemplateParser.new(config)
42
+ @template_parser = TemplateParser.new(@command)
41
43
  filenames = Dir.glob("#{@template_parser.template_dir}/*.yml")
42
44
  templates = @template_parser.parse(filenames)
43
45
 
@@ -97,8 +99,4 @@ class DoctorService
97
99
  .join("\n")
98
100
  progress.puts("\n#{Shell.color("DEPRECATED: #{message}", :yellow)}\n#{list}\n\n")
99
101
  end
100
-
101
- def progress
102
- $stderr
103
- end
104
102
  end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MaintenanceMode
4
+ extend Forwardable
5
+
6
+ def_delegators :@command, :config, :progress, :cp, :step, :run_cpflow_command
7
+
8
+ def initialize(command)
9
+ @command = command
10
+ end
11
+
12
+ def enabled?
13
+ validate_domain_exists!
14
+ cp.domain_workload_matches?(domain_data, maintenance_workload)
15
+ end
16
+
17
+ def disabled?
18
+ validate_domain_exists!
19
+ cp.domain_workload_matches?(domain_data, one_off_workload)
20
+ end
21
+
22
+ def enable!
23
+ if enabled?
24
+ progress.puts("Maintenance mode is already enabled for app '#{config.app}'.")
25
+ else
26
+ enable_maintenance_mode
27
+ end
28
+ end
29
+
30
+ def disable!
31
+ if disabled?
32
+ progress.puts("Maintenance mode is already disabled for app '#{config.app}'.")
33
+ else
34
+ disable_maintenance_mode
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def enable_maintenance_mode
41
+ validate_maintenance_workload_exists!
42
+
43
+ start_or_stop_maintenance_workload(:start)
44
+ switch_domain_workload(to: maintenance_workload)
45
+ start_or_stop_all_workloads(:stop)
46
+
47
+ progress.puts("\nMaintenance mode enabled for app '#{config.app}'.")
48
+ end
49
+
50
+ def disable_maintenance_mode
51
+ validate_maintenance_workload_exists!
52
+
53
+ start_or_stop_maintenance_workload(:start)
54
+ switch_domain_workload(to: one_off_workload)
55
+ start_or_stop_all_workloads(:stop)
56
+
57
+ progress.puts("\nMaintenance mode disabled for app '#{config.app}'.")
58
+ end
59
+
60
+ def validate_domain_exists!
61
+ return if domain_data
62
+
63
+ raise "Can't find domain. " \
64
+ "Maintenance mode is only supported for domains that use path based routing mode " \
65
+ "and have a route configured for the prefix '/' on either port 80 or 443."
66
+ end
67
+
68
+ def validate_maintenance_workload_exists!
69
+ cp.fetch_workload!(maintenance_workload)
70
+ end
71
+
72
+ def start_or_stop_all_workloads(action)
73
+ run_cpflow_command("ps:#{action}", "-a", config.app, "--wait")
74
+
75
+ progress.puts
76
+ end
77
+
78
+ def start_or_stop_maintenance_workload(action)
79
+ run_cpflow_command("ps:#{action}", "-a", config.app, "-w", maintenance_workload, "--wait")
80
+
81
+ progress.puts
82
+ end
83
+
84
+ def switch_domain_workload(to:)
85
+ step("Switching workload for domain '#{domain_data['name']}' to '#{to}'") do
86
+ cp.set_domain_workload(domain_data, to)
87
+
88
+ # Give it a bit of time for the domain to update
89
+ Kernel.sleep(30)
90
+ end
91
+
92
+ progress.puts
93
+ end
94
+
95
+ def domain_data
96
+ @domain_data ||=
97
+ if config.domain
98
+ cp.fetch_domain(config.domain)
99
+ else
100
+ cp.find_domain_for([one_off_workload, maintenance_workload])
101
+ end
102
+ end
103
+
104
+ def one_off_workload
105
+ @one_off_workload ||= config[:one_off_workload]
106
+ end
107
+
108
+ def maintenance_workload
109
+ @maintenance_workload ||= config.current[:maintenance_workload] || "maintenance"
110
+ end
111
+ end
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TemplateParser
4
- attr_reader :config, :deprecated_variables
4
+ extend Forwardable
5
5
 
6
- def initialize(config)
7
- @config = config
6
+ def_delegators :@command, :config, :cp
7
+
8
+ attr_reader :deprecated_variables
9
+
10
+ def initialize(command)
11
+ @command = command
8
12
  end
9
13
 
10
14
  def template_dir
@@ -69,8 +73,4 @@ class TemplateParser
69
73
  "APP_IMAGE" => "{{APP_IMAGE}}"
70
74
  }
71
75
  end
72
-
73
- def cp
74
- @cp ||= Controlplane.new(config)
75
- end
76
76
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpflow
4
- VERSION = "3.0.1"
5
- MIN_CPLN_VERSION = "2.0.1"
4
+ VERSION = "4.0.1"
5
+ MIN_CPLN_VERSION = "3.1.0"
6
6
  end
data/lib/cpflow.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "date"
4
+ require "forwardable"
4
5
  require "dotenv/load"
5
6
  require "cgi"
6
7
  require "json"
@@ -30,25 +31,7 @@ at_exit do
30
31
  end
31
32
  end
32
33
 
33
- # Fix for https://github.com/erikhuda/thor/issues/398
34
- # Copied from https://github.com/rails/thor/issues/398#issuecomment-622988390
35
- class Thor
36
- module Shell
37
- class Basic
38
- def print_wrapped(message, options = {})
39
- indent = (options[:indent] || 0).to_i
40
- if indent.zero?
41
- stdout.puts(message)
42
- else
43
- message.each_line do |message_line|
44
- stdout.print(" " * indent)
45
- stdout.puts(message_line.chomp)
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
34
+ require_relative "patches/thor"
52
35
 
53
36
  module Cpflow
54
37
  class Error < StandardError; end
@@ -226,12 +209,14 @@ module Cpflow
226
209
 
227
210
  Cpflow::Cli.show_info_header(config) if with_info_header
228
211
 
212
+ command = command_class.new(config)
213
+
229
214
  if validations.any? && ENV.fetch("DISABLE_VALIDATIONS", nil) != "true"
230
- doctor = DoctorService.new(config)
215
+ doctor = DoctorService.new(command)
231
216
  doctor.run_validations(validations, silent_if_passing: true)
232
217
  end
233
218
 
234
- command_class.new(config).call
219
+ command.call
235
220
  rescue RuntimeError => e
236
221
  ::Shell.abort(e.message)
237
222
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Thor
4
+ # Fix for https://github.com/erikhuda/thor/issues/398
5
+ # Copied from https://github.com/rails/thor/issues/398#issuecomment-622988390
6
+ module Shell
7
+ class Basic
8
+ def print_wrapped(message, options = {})
9
+ indent = (options[:indent] || 0).to_i
10
+ if indent.zero?
11
+ stdout.puts(message)
12
+ else
13
+ message.each_line do |message_line|
14
+ stdout.print(" " * indent)
15
+ stdout.puts(message_line.chomp)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # Fix for https://github.com/rails/thor/issues/742
23
+ def self.basename
24
+ @package_name || super
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-06-26 00:00:00.000000000 Z
12
+ date: 2024-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dotenv
@@ -79,6 +79,7 @@ files:
79
79
  - ".github/workflows/check_cpln_links.yml"
80
80
  - ".github/workflows/command_docs.yml"
81
81
  - ".github/workflows/rspec-shared.yml"
82
+ - ".github/workflows/rspec-specific.yml"
82
83
  - ".github/workflows/rspec.yml"
83
84
  - ".github/workflows/rubocop.yml"
84
85
  - ".gitignore"
@@ -148,6 +149,7 @@ files:
148
149
  - lib/core/controlplane_api_direct.rb
149
150
  - lib/core/doctor_service.rb
150
151
  - lib/core/helpers.rb
152
+ - lib/core/maintenance_mode.rb
151
153
  - lib/core/shell.rb
152
154
  - lib/core/template_parser.rb
153
155
  - lib/cpflow.rb
@@ -159,6 +161,7 @@ files:
159
161
  - lib/generator_templates/templates/app.yml
160
162
  - lib/generator_templates/templates/postgres.yml
161
163
  - lib/generator_templates/templates/rails.yml
164
+ - lib/patches/thor.rb
162
165
  - rakelib/create_release.rake
163
166
  - script/add_command
164
167
  - script/check_command_docs