cpl 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +22 -1
- data/Gemfile.lock +2 -2
- data/README.md +12 -3
- data/docs/commands.md +30 -6
- data/docs/secrets-and-env-values.md +42 -0
- data/docs/tips.md +1 -40
- data/examples/controlplane.yml +12 -3
- data/lib/command/apply_template.rb +70 -80
- data/lib/command/base.rb +82 -71
- data/lib/command/build_image.rb +2 -2
- data/lib/command/cleanup_images.rb +1 -1
- data/lib/command/cleanup_stale_apps.rb +1 -1
- data/lib/command/copy_image_from_upstream.rb +3 -3
- data/lib/command/delete.rb +17 -5
- data/lib/command/deploy_image.rb +6 -21
- data/lib/command/doctor.rb +47 -0
- data/lib/command/latest_image.rb +1 -1
- data/lib/command/no_command.rb +1 -0
- data/lib/command/promote_app_from_upstream.rb +1 -1
- data/lib/command/run.rb +1 -1
- data/lib/command/setup_app.rb +80 -16
- data/lib/command/test.rb +1 -0
- data/lib/command/version.rb +1 -0
- data/lib/core/config.rb +40 -12
- data/lib/core/controlplane.rb +53 -0
- data/lib/core/controlplane_api.rb +13 -7
- data/lib/core/controlplane_api_direct.rb +1 -1
- data/lib/core/doctor_service.rb +104 -0
- data/lib/core/helpers.rb +10 -0
- data/lib/core/template_parser.rb +76 -0
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +24 -6
- data/templates/app.yml +0 -5
- metadata +6 -4
- data/lib/core/controlplane_api_cli.rb +0 -10
- data/templates/secrets.yml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 468f47cb0e1cf3cdb710b885949188c68f40fd74ad4236379a5a6c6fd55739c1
|
4
|
+
data.tar.gz: fc83d4ef5ee3ded08d52ca5f2df92e5ee261df6fcefd27f673452d0ba265a650
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dac1051680d2b3c69473636a9babd19b8799ea6e2eaadbb26582836641f7a73e843e4a26c32f41206edb0a6b21ab89b9b62cc08087360d75a562c3b6bb40188d
|
7
|
+
data.tar.gz: 52ca1f46ff0d459f450e1a1bd82b6efce780e9b6480ebbda955722eef4bea3a98d71cdaff076691b4cfe93e77c42285f358bfb4ba9adf857c961108302a4f5d6
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -14,6 +14,26 @@ 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 release script was not running from the app image. [PR 183](https://github.com/shakacode/control-plane-flow/pull/183) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
20
|
+
- Fixed issue where deprecated options were not being warned. [PR 183](https://github.com/shakacode/control-plane-flow/pull/183) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
21
|
+
|
22
|
+
### Added
|
23
|
+
|
24
|
+
- Added post-creation hook to `setup-app` command (configurable through `hooks.post_creation` in `controlplane.yml`). [PR 183](https://github.com/shakacode/control-plane-flow/pull/183) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
25
|
+
- Added pre-deletion hook to `delete` command (configurable through `hooks.pre_deletion` in `controlplane.yml`). [PR 183](https://github.com/shakacode/control-plane-flow/pull/183) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
26
|
+
- Added `doctor` command to run validations. [PR 185](https://github.com/shakacode/control-plane-flow/pull/185) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
|
30
|
+
- `cpl` now sets `CPLN_SKIP_UPDATE_CHECK` to `true` for all internal `cpln` calls, which disables the version check and prevents cluttering the logs. [PR 180](https://github.com/shakacode/control-plane-flow/pull/180) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
31
|
+
- `setup-app` command now automatically creates a secret, policy, and identity for the app if they do not exist. The `--skip-secrets-setup` option prevents this behavior. [PR 181](https://github.com/shakacode/control-plane-flow/pull/181) by [Rafael Gomes](https://github.com/rafaelgomesxyz). [PR 190](https://github.com/shakacode/control-plane-flow/pull/190) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
|
32
|
+
- 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).
|
33
|
+
- 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).
|
34
|
+
|
35
|
+
## [2.0.2] - 2024-05-17
|
36
|
+
|
17
37
|
- 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).
|
18
38
|
|
19
39
|
## [2.0.1] - 2024-05-15
|
@@ -194,7 +214,8 @@ _Please add entries here for your pull requests that have not yet been released.
|
|
194
214
|
|
195
215
|
- Initial release
|
196
216
|
|
197
|
-
[Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v2.0.
|
217
|
+
[Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v2.0.2...HEAD
|
218
|
+
[2.0.2]: https://github.com/shakacode/control-plane-flow/compare/v2.0.1...v2.0.2
|
198
219
|
[2.0.1]: https://github.com/shakacode/control-plane-flow/compare/v2.0.0...v2.0.1
|
199
220
|
[2.0.0]: https://github.com/shakacode/control-plane-flow/compare/v1.4.0...v2.0.0
|
200
221
|
[1.4.0]: https://github.com/shakacode/control-plane-flow/compare/v1.3.0...v1.4.0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cpl (2.0
|
4
|
+
cpl (2.1.0)
|
5
5
|
debug (~> 1.7.1)
|
6
6
|
dotenv (~> 2.8.1)
|
7
7
|
jwt (~> 2.8.1)
|
@@ -49,7 +49,7 @@ GEM
|
|
49
49
|
racc (1.7.3)
|
50
50
|
rainbow (3.1.1)
|
51
51
|
rake (13.2.1)
|
52
|
-
rdoc (6.
|
52
|
+
rdoc (6.7.0)
|
53
53
|
psych (>= 4.0.0)
|
54
54
|
regexp_parser (2.9.0)
|
55
55
|
reline (0.5.7)
|
data/README.md
CHANGED
@@ -196,9 +196,6 @@ aliases:
|
|
196
196
|
# 2. Each file can contain many objects, such as in the case of templates that create a resource, like `postgres`.
|
197
197
|
# 3. While the naming often corresponds to a workload or other object name, the naming is arbitrary.
|
198
198
|
# Naming does not need to match anything other than the file name without the `.yml` extension.
|
199
|
-
#
|
200
|
-
# If you're going to use secrets, you need to apply the `secrets.yml` template separately (one-time setup):
|
201
|
-
# `cpl apply-template secrets -a my-app`
|
202
199
|
setup_app_templates:
|
203
200
|
- app
|
204
201
|
- redis
|
@@ -207,6 +204,9 @@ aliases:
|
|
207
204
|
- rails
|
208
205
|
- sidekiq
|
209
206
|
|
207
|
+
# Skips secrets setup when running `cpl setup-app`.
|
208
|
+
skip_secrets_setup: true
|
209
|
+
|
210
210
|
# Only needed if using a custom secrets name.
|
211
211
|
# The default is '{APP_PREFIX}-secrets'. For example:
|
212
212
|
# - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
|
@@ -273,6 +273,15 @@ apps:
|
|
273
273
|
# e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
|
274
274
|
match_if_app_name_starts_with: true
|
275
275
|
|
276
|
+
# Hooks can be either a script path that exists in the app image or a command.
|
277
|
+
# They're run in the context of `cpl run` with the latest image.
|
278
|
+
hooks:
|
279
|
+
# Used by the command `cpl setup-app` to run a hook after creating the app.
|
280
|
+
post_creation: bundle exec rake db:prepare
|
281
|
+
|
282
|
+
# Used by the command `cpl delete` to run a hook before deleting the app.
|
283
|
+
pre_deletion: bundle exec rake db:drop
|
284
|
+
|
276
285
|
my-app-production:
|
277
286
|
<<: *common
|
278
287
|
|
data/docs/commands.md
CHANGED
@@ -109,6 +109,9 @@ cpl copy-image-from-upstream -a $APP_NAME --upstream-token $UPSTREAM_TOKEN --ima
|
|
109
109
|
- Deletes the whole app (GVC with all workloads, all volumesets and all images) or a specific workload
|
110
110
|
- Also unbinds the app from the secrets policy, as long as both the identity and the policy exist (and are bound)
|
111
111
|
- Will ask for explicit user confirmation
|
112
|
+
- Runs a pre-deletion hook before the app is deleted if `hooks.pre_deletion` is specified in the `.controlplane/controlplane.yml` file
|
113
|
+
- If the hook exits with a non-zero code, the command will stop executing and also exit with a non-zero code
|
114
|
+
- Use `--skip-pre-deletion-hook` to skip the hook if specified in `controlplane.yml`
|
112
115
|
|
113
116
|
```sh
|
114
117
|
# Deletes the whole app (GVC with all workloads, all volumesets and all images).
|
@@ -121,14 +124,29 @@ cpl delete -a $APP_NAME -w $WORKLOAD_NAME
|
|
121
124
|
### `deploy-image`
|
122
125
|
|
123
126
|
- Deploys the latest image to app workloads
|
124
|
-
-
|
127
|
+
- Runs a release script before deploying if `release_script` is specified in the `.controlplane/controlplane.yml` file and `--run-release-phase` is provided
|
125
128
|
- The release script is run in the context of `cpl run` with the latest image
|
126
|
-
-
|
129
|
+
- If the release script exits with a non-zero code, the command will stop executing and also exit with a non-zero code
|
127
130
|
|
128
131
|
```sh
|
129
132
|
cpl deploy-image -a $APP_NAME
|
130
133
|
```
|
131
134
|
|
135
|
+
### `doctor`
|
136
|
+
|
137
|
+
- Runs validations
|
138
|
+
|
139
|
+
```sh
|
140
|
+
# Runs all validations that don't require additional options by default.
|
141
|
+
cpl doctor
|
142
|
+
|
143
|
+
# Runs config validation.
|
144
|
+
cpl doctor --validations config
|
145
|
+
|
146
|
+
# Runs templates validation (requires app).
|
147
|
+
cpl doctor --validations templates -a $APP_NAME
|
148
|
+
```
|
149
|
+
|
132
150
|
### `env`
|
133
151
|
|
134
152
|
- Displays app-specific environment variables
|
@@ -276,7 +294,7 @@ cpl open-console -a $APP_NAME
|
|
276
294
|
- Runs `cpl copy-image-from-upstream` to copy the latest image from upstream
|
277
295
|
- Runs `cpl deploy-image` to deploy the image
|
278
296
|
- If `.controlplane/controlplane.yml` includes the `release_script`, `cpl deploy-image` will use the `--run-release-phase` option
|
279
|
-
-
|
297
|
+
- If the release script exits with a non-zero code, the command will stop executing and also exit with a non-zero code
|
280
298
|
|
281
299
|
```sh
|
282
300
|
cpl promote-app-from-upstream -a $APP_NAME -t $UPSTREAM_TOKEN
|
@@ -407,9 +425,15 @@ cpl run -a $APP_NAME --entrypoint /app/alternative-entrypoint.sh -- rails db:mig
|
|
407
425
|
|
408
426
|
- Creates an app and all its workloads
|
409
427
|
- Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
|
410
|
-
- This should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
|
411
|
-
-
|
412
|
-
-
|
428
|
+
- This should only be used for temporary apps like review apps, never for persistent apps like production or staging (to update workloads for those, use 'cpl apply-template' instead)
|
429
|
+
- Configures app to have org-level secrets with default name "{APP_PREFIX}-secrets"
|
430
|
+
using org-level policy with default name "{APP_PREFIX}-secrets-policy" (names can be customized, see docs)
|
431
|
+
- Creates identity for secrets if it does not exist
|
432
|
+
- Use `--skip-secrets-setup` to prevent the automatic setup of secrets,
|
433
|
+
or set it through `skip_secrets_setup` in the `.controlplane/controlplane.yml` file
|
434
|
+
- Runs a post-creation hook after the app is created if `hooks.post_creation` is specified in the `.controlplane/controlplane.yml` file
|
435
|
+
- If the hook exits with a non-zero code, the command will stop executing and also exit with a non-zero code
|
436
|
+
- Use `--skip-post-creation-hook` to skip the hook if specified in `controlplane.yml`
|
413
437
|
|
414
438
|
```sh
|
415
439
|
cpl setup-app -a $APP_NAME
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Secrets and ENV Values
|
2
|
+
|
3
|
+
You can store ENV values used by a container (within a workload) within Control Plane at the following levels:
|
4
|
+
|
5
|
+
1. Workload Container
|
6
|
+
2. GVC
|
7
|
+
|
8
|
+
For your "review apps," it is convenient to have simple ENVs stored in plain text in your source code. You will want to
|
9
|
+
keep some ENVs, like the Rails' `SECRET_KEY_BASE`, out of your source code. For staging and production apps, you will
|
10
|
+
set these values directly at the GVC or workload levels, so none of these ENV values are committed to the source code.
|
11
|
+
|
12
|
+
For storing ENVs in the source code, we can use a level of indirection so that you can store an ENV value in your source
|
13
|
+
code like `cpln://secret/my-app-review-env-secrets.SECRET_KEY_BASE` and then have the secret value stored at the org
|
14
|
+
level, which applies to your GVCs mapped to that org.
|
15
|
+
|
16
|
+
For setting up secrets, you'll need:
|
17
|
+
|
18
|
+
- **Org-level Secret:** This is where the values will be stored.
|
19
|
+
- **GVC Identity:** An identity that must be associated with each workload that requires access to the secret.
|
20
|
+
- **Org-level Policy:** A policy that binds the identity to the secret, granting the necessary permissions for the workload to access the secret.
|
21
|
+
|
22
|
+
You can do this during the initial app setup, like this:
|
23
|
+
|
24
|
+
1. Add the template for `app` to `.controlplane/templates`
|
25
|
+
2. Ensure that the `app` template is listed in `setup_app_templates` for the app in `.controlplane/controlplane.yml`
|
26
|
+
3. Run `cpl setup-app -a $APP_NAME`
|
27
|
+
4. The secrets, secrets policy and identity will be automatically created, along with the proper binding
|
28
|
+
5. In the Control Plane console, upper left "Manage Org" menu, click on "Secrets"
|
29
|
+
6. Find the created secret (it will be in the `$APP_PREFIX-secrets` format) and add the secret env vars there
|
30
|
+
7. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/$APP_PREFIX-secrets.SOME_VAR`)
|
31
|
+
|
32
|
+
Here are the manual steps for reference. We recommend that you follow the steps above:
|
33
|
+
|
34
|
+
1. In the upper left of the Control Plane console, "Manage Org" menu, click on "Secrets"
|
35
|
+
2. Create a secret with `Secret Type: Dictionary` (e.g., `my-secrets`) and add the secret env vars there
|
36
|
+
3. In the upper left "Manage GVC" menu, click on "Identities"
|
37
|
+
4. Create an identity (e.g., `my-identity`)
|
38
|
+
5. Navigate to the workload that you want to associate with the identity created
|
39
|
+
6. Click "Identity" on the left menu and select the identity created
|
40
|
+
7. In the lower left "Access Control" menu, click on "Policies"
|
41
|
+
8. Create a policy with `Target Kind: Secret` and add a binding with the `reveal` permission for the identity created
|
42
|
+
9. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/my-secrets.SOME_VAR`)
|
data/docs/tips.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
1. [GVCs vs. Orgs](#gvcs-vs-orgs)
|
4
4
|
2. [RAM](#ram)
|
5
5
|
3. [Remote IP](#remote-ip)
|
6
|
-
4. [ENV Values](
|
6
|
+
4. [Secrets and ENV Values](/docs/secrets-and-env-values.md)
|
7
7
|
5. [CI](#ci)
|
8
8
|
6. [Memcached](#memcached)
|
9
9
|
7. [Sidekiq](#sidekiq)
|
@@ -70,45 +70,6 @@ pick those up and automatically populate `request.remote_ip`.
|
|
70
70
|
|
71
71
|
So `REMOTE_ADDR` should not be used directly, only `request.remote_ip`.
|
72
72
|
|
73
|
-
## ENV Values
|
74
|
-
|
75
|
-
You can store ENV values used by a container (within a workload) within Control Plane at the following levels:
|
76
|
-
|
77
|
-
1. Workload Container
|
78
|
-
2. GVC
|
79
|
-
|
80
|
-
For your "review apps," it is convenient to have simple ENVs stored in plain text in your source code. You will want to
|
81
|
-
keep some ENVs, like the Rails' `SECRET_KEY_BASE`, out of your source code. For staging and production apps, you will
|
82
|
-
set these values directly at the GVC or workload levels, so none of these ENV values are committed to the source code.
|
83
|
-
|
84
|
-
For storing ENVs in the source code, we can use a level of indirection so that you can store an ENV value in your source
|
85
|
-
code like `cpln://secret/my-app-review-env-secrets.SECRET_KEY_BASE` and then have the secret value stored at the org
|
86
|
-
level, which applies to your GVCs mapped to that org.
|
87
|
-
|
88
|
-
You can do this during the initial app setup, like this:
|
89
|
-
|
90
|
-
1. Add the templates for `app` and `secrets` to `.controlplane/templates`
|
91
|
-
2. Ensure that the `app` template includes the `identity`
|
92
|
-
3. Ensure that the `app` template is listed in `setup_app_templates` for the app in `.controlplane/controlplane.yml`
|
93
|
-
4. Run `cpl apply-template secrets -a $APP_NAME` (one-time setup)
|
94
|
-
5. Run `cpl setup-app -a $APP_NAME`
|
95
|
-
6. The secrets, secrets policy and identity will be automatically created, along with the proper binding
|
96
|
-
7. In the Control Plane console, upper left "Manage Org" menu, click on "Secrets"
|
97
|
-
8. Find the created secret (it will be in the `$APP_PREFIX-secrets` format) and add the secret env vars there
|
98
|
-
9. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/$APP_PREFIX-secrets.SOME_VAR`)
|
99
|
-
|
100
|
-
Here are the manual steps for reference. We recommend that you follow the steps above:
|
101
|
-
|
102
|
-
1. In the upper left of the Control Plane console, "Manage Org" menu, click on "Secrets"
|
103
|
-
2. Create a secret with `Secret Type: Dictionary` (e.g., `my-secrets`) and add the secret env vars there
|
104
|
-
3. In the upper left "Manage GVC" menu, click on "Identities"
|
105
|
-
4. Create an identity (e.g., `my-identity`)
|
106
|
-
5. Navigate to the workload that you want to associate with the identity created
|
107
|
-
6. Click "Identity" on the left menu and select the identity created
|
108
|
-
7. In the lower left "Access Control" menu, click on "Policies"
|
109
|
-
8. Create a policy with `Target Kind: Secret` and add a binding with the `reveal` permission for the identity created
|
110
|
-
9. Use `cpln://secret/...` in the app to access the secret env vars (e.g., `cpln://secret/my-secrets.SOME_VAR`)
|
111
|
-
|
112
73
|
## CI
|
113
74
|
|
114
75
|
**Note:** Docker builds much slower on Apple Silicon, so try configuring CI to build the images when using Apple
|
data/examples/controlplane.yml
CHANGED
@@ -31,9 +31,6 @@ aliases:
|
|
31
31
|
# 2. Each file can contain many objects, such as in the case of templates that create a resource, like `postgres`.
|
32
32
|
# 3. While the naming often corresponds to a workload or other object name, the naming is arbitrary.
|
33
33
|
# Naming does not need to match anything other than the file name without the `.yml` extension.
|
34
|
-
#
|
35
|
-
# If you're going to use secrets, you need to apply the `secrets.yml` template separately (one-time setup):
|
36
|
-
# `cpl apply-template secrets -a my-app`
|
37
34
|
setup_app_templates:
|
38
35
|
- app
|
39
36
|
- redis
|
@@ -42,6 +39,9 @@ aliases:
|
|
42
39
|
- rails
|
43
40
|
- sidekiq
|
44
41
|
|
42
|
+
# Uncomment next line to skips secrets setup when running `cpl setup-app`.
|
43
|
+
# skip_secrets_setup: true
|
44
|
+
|
45
45
|
# Only needed if using a custom secrets name.
|
46
46
|
# The default is '{APP_PREFIX}-secrets'. For example:
|
47
47
|
# - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
|
@@ -108,6 +108,15 @@ apps:
|
|
108
108
|
# e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
|
109
109
|
match_if_app_name_starts_with: true
|
110
110
|
|
111
|
+
# Hooks can be either a script path that exists in the app image or a command.
|
112
|
+
# They're run in the context of `cpl run` with the latest image.
|
113
|
+
hooks:
|
114
|
+
# Used by the command `cpl setup-app` to run a hook after creating the app.
|
115
|
+
post_creation: bundle exec rake db:prepare
|
116
|
+
|
117
|
+
# Used by the command `cpl delete` to run a hook before deleting the app.
|
118
|
+
pre_deletion: bundle exec rake db:drop
|
119
|
+
|
111
120
|
my-app-production:
|
112
121
|
<<: *common
|
113
122
|
|
@@ -8,7 +8,8 @@ module Command
|
|
8
8
|
OPTIONS = [
|
9
9
|
app_option(required: true),
|
10
10
|
location_option,
|
11
|
-
skip_confirm_option
|
11
|
+
skip_confirm_option,
|
12
|
+
add_app_identity_option
|
12
13
|
].freeze
|
13
14
|
DESCRIPTION = "Applies application-specific configs from templates"
|
14
15
|
LONG_DESCRIPTION = <<~DESC
|
@@ -39,45 +40,27 @@ module Command
|
|
39
40
|
cpl apply-template app postgres redis rails -a $APP_NAME
|
40
41
|
```
|
41
42
|
EX
|
43
|
+
VALIDATIONS = %w[config templates].freeze
|
44
|
+
|
45
|
+
def call # rubocop:disable Metrics/MethodLength
|
46
|
+
@template_parser = TemplateParser.new(config)
|
47
|
+
@names_to_filenames = config.args.to_h do |name|
|
48
|
+
[name, @template_parser.template_filename(name)]
|
49
|
+
end
|
42
50
|
|
43
|
-
def call # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
44
51
|
ensure_templates!
|
45
52
|
|
46
53
|
@created_items = []
|
47
54
|
@failed_templates = []
|
48
55
|
@skipped_templates = []
|
49
56
|
|
50
|
-
|
51
|
-
|
52
|
-
pending_templates
|
53
|
-
|
54
|
-
|
55
|
-
else
|
56
|
-
confirm_workload(template)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
progress.puts if @asked_for_confirmation
|
61
|
-
|
62
|
-
@deprecated_variables = []
|
63
|
-
|
64
|
-
pending_templates.each do |template, filename|
|
65
|
-
step("Applying template '#{template}'", abort_on_error: false) do
|
66
|
-
items = apply_template(filename)
|
67
|
-
unless items
|
68
|
-
report_failure(template)
|
69
|
-
next false
|
70
|
-
end
|
71
|
-
|
72
|
-
items.each do |item|
|
73
|
-
report_success(item)
|
74
|
-
end
|
75
|
-
true
|
76
|
-
end
|
57
|
+
templates = @template_parser.parse(@names_to_filenames.values)
|
58
|
+
pending_templates = confirm_templates(templates)
|
59
|
+
add_app_identity_template(pending_templates) if config.options[:add_app_identity]
|
60
|
+
pending_templates.each do |template|
|
61
|
+
apply_template(template)
|
77
62
|
end
|
78
63
|
|
79
|
-
warn_deprecated_variables
|
80
|
-
|
81
64
|
print_created_items
|
82
65
|
print_failed_templates
|
83
66
|
print_skipped_templates
|
@@ -87,18 +70,21 @@ module Command
|
|
87
70
|
|
88
71
|
private
|
89
72
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
73
|
+
def template_kind(template)
|
74
|
+
case template["kind"]
|
75
|
+
when "gvc"
|
76
|
+
"app"
|
77
|
+
else
|
78
|
+
template["kind"]
|
93
79
|
end
|
94
80
|
end
|
95
81
|
|
96
82
|
def ensure_templates!
|
97
|
-
missing_templates =
|
83
|
+
missing_templates = @names_to_filenames.reject { |_, filename| File.exist?(filename) }
|
98
84
|
return if missing_templates.empty?
|
99
85
|
|
100
|
-
missing_templates_str = missing_templates.map do |
|
101
|
-
" - #{
|
86
|
+
missing_templates_str = missing_templates.map do |name, filename|
|
87
|
+
" - #{name} (#{filename})"
|
102
88
|
end.join("\n")
|
103
89
|
progress.puts("#{Shell.color('Missing templates:', :red)}\n#{missing_templates_str}\n\n")
|
104
90
|
|
@@ -113,10 +99,10 @@ module Command
|
|
113
99
|
end
|
114
100
|
|
115
101
|
def confirm_app(template)
|
116
|
-
app = cp.fetch_gvc
|
102
|
+
app = cp.fetch_gvc(template["name"])
|
117
103
|
return true unless app
|
118
104
|
|
119
|
-
confirmed = confirm_apply("App '#{
|
105
|
+
confirmed = confirm_apply("App '#{template['name']}' already exists, do you want to re-create it?")
|
120
106
|
return true if confirmed
|
121
107
|
|
122
108
|
report_skipped(template)
|
@@ -124,63 +110,67 @@ module Command
|
|
124
110
|
end
|
125
111
|
|
126
112
|
def confirm_workload(template)
|
127
|
-
workload = cp.fetch_workload(template)
|
113
|
+
workload = cp.fetch_workload(template["name"])
|
128
114
|
return true unless workload
|
129
115
|
|
130
|
-
confirmed = confirm_apply("Workload '#{template}' already exists, do you want to re-create it?")
|
116
|
+
confirmed = confirm_apply("Workload '#{template['name']}' already exists, do you want to re-create it?")
|
131
117
|
return true if confirmed
|
132
118
|
|
133
119
|
report_skipped(template)
|
134
120
|
false
|
135
121
|
end
|
136
122
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
123
|
+
def confirm_templates(templates) # rubocop:disable Metrics/MethodLength
|
124
|
+
@asked_for_confirmation = false
|
125
|
+
|
126
|
+
pending_templates = templates.select do |template|
|
127
|
+
case template["kind"]
|
128
|
+
when "gvc"
|
129
|
+
confirm_app(template)
|
130
|
+
when "workload"
|
131
|
+
confirm_workload(template)
|
132
|
+
else
|
133
|
+
true
|
134
|
+
end
|
135
|
+
end
|
149
136
|
|
150
|
-
|
137
|
+
progress.puts if @asked_for_confirmation
|
138
|
+
|
139
|
+
pending_templates
|
140
|
+
end
|
151
141
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
.gsub("APP_GVC", config.app)
|
156
|
-
.gsub("APP_LOCATION", config.location)
|
157
|
-
.gsub("APP_IMAGE", latest_image)
|
142
|
+
def add_app_identity_template(templates)
|
143
|
+
app_template_index = templates.index { |template| template["name"] == config.app }
|
144
|
+
app_identity_template_index = templates.index { |template| template["name"] == config.identity }
|
158
145
|
|
159
|
-
|
160
|
-
|
146
|
+
return unless app_template_index && app_identity_template_index.nil?
|
147
|
+
|
148
|
+
# Adding the identity template right after the app template is important since:
|
149
|
+
# a) we can't create the identity at the beginning because the app doesn't exist yet
|
150
|
+
# b) we also can't create it at the end because any workload templates associated with it will fail to apply
|
151
|
+
templates.insert(app_template_index + 1, build_app_identity_hash)
|
161
152
|
end
|
162
153
|
|
163
|
-
def
|
154
|
+
def build_app_identity_hash
|
164
155
|
{
|
165
|
-
"
|
166
|
-
"
|
167
|
-
"APP_LOCATION" => "{{APP_LOCATION}}",
|
168
|
-
"APP_IMAGE" => "{{APP_IMAGE}}"
|
156
|
+
"kind" => "identity",
|
157
|
+
"name" => config.identity
|
169
158
|
}
|
170
159
|
end
|
171
160
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
161
|
+
def apply_template(template) # rubocop:disable Metrics/MethodLength
|
162
|
+
step("Applying template for #{template_kind(template)} '#{template['name']}'", abort_on_error: false) do
|
163
|
+
items = cp.apply_hash(template)
|
164
|
+
unless items
|
165
|
+
report_failure(template)
|
166
|
+
next false
|
167
|
+
end
|
179
168
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
169
|
+
items.each do |item|
|
170
|
+
report_success(item)
|
171
|
+
end
|
172
|
+
true
|
173
|
+
end
|
184
174
|
end
|
185
175
|
|
186
176
|
def report_success(item)
|
@@ -205,14 +195,14 @@ module Command
|
|
205
195
|
def print_failed_templates
|
206
196
|
return unless @failed_templates.any?
|
207
197
|
|
208
|
-
failed = @failed_templates.map { |template| " - #{template}" }.join("\n")
|
198
|
+
failed = @failed_templates.map { |template| " - [#{template_kind(template)}] #{template['name']}" }.join("\n")
|
209
199
|
progress.puts("\n#{Shell.color('Failed to apply templates:', :red)}\n#{failed}")
|
210
200
|
end
|
211
201
|
|
212
202
|
def print_skipped_templates
|
213
203
|
return unless @skipped_templates.any?
|
214
204
|
|
215
|
-
skipped = @skipped_templates.map { |template| " - #{template}" }.join("\n")
|
205
|
+
skipped = @skipped_templates.map { |template| " - [#{template_kind(template)}] #{template['name']}" }.join("\n")
|
216
206
|
progress.puts("\n#{Shell.color('Skipped templates (already exist):', :blue)}\n#{skipped}")
|
217
207
|
end
|
218
208
|
end
|