cpl 1.3.0 → 2.0.0.rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/command_docs.yml +1 -1
- data/.github/workflows/rspec-shared.yml +56 -0
- data/.github/workflows/rspec.yml +19 -31
- data/.github/workflows/rubocop.yml +2 -10
- data/.gitignore +2 -0
- data/.simplecov_spawn.rb +10 -0
- data/CHANGELOG.md +28 -1
- data/CONTRIBUTING.md +32 -2
- data/Gemfile.lock +38 -29
- data/README.md +43 -17
- data/cpl.gemspec +2 -1
- data/docs/commands.md +68 -59
- data/docs/dns.md +6 -0
- data/docs/migrating.md +10 -10
- data/docs/tips.md +15 -3
- data/examples/circleci.yml +3 -3
- data/examples/controlplane.yml +35 -9
- data/lib/command/apply_template.rb +66 -18
- data/lib/command/base.rb +168 -27
- data/lib/command/build_image.rb +4 -9
- data/lib/command/cleanup_stale_apps.rb +1 -3
- data/lib/command/copy_image_from_upstream.rb +0 -7
- data/lib/command/delete.rb +39 -7
- data/lib/command/deploy_image.rb +35 -2
- data/lib/command/exists.rb +1 -1
- data/lib/command/generate.rb +1 -1
- data/lib/command/info.rb +7 -3
- data/lib/command/logs.rb +22 -2
- data/lib/command/maintenance_off.rb +1 -1
- data/lib/command/maintenance_on.rb +1 -1
- data/lib/command/open.rb +2 -2
- data/lib/command/open_console.rb +2 -2
- data/lib/command/promote_app_from_upstream.rb +5 -25
- data/lib/command/ps.rb +1 -1
- data/lib/command/ps_start.rb +2 -1
- data/lib/command/ps_stop.rb +40 -8
- data/lib/command/ps_wait.rb +3 -2
- data/lib/command/run.rb +430 -68
- data/lib/command/setup_app.rb +22 -2
- data/lib/constants/exit_code.rb +7 -0
- data/lib/core/config.rb +11 -3
- data/lib/core/controlplane.rb +126 -47
- data/lib/core/controlplane_api.rb +15 -1
- data/lib/core/controlplane_api_cli.rb +3 -3
- data/lib/core/controlplane_api_direct.rb +33 -5
- data/lib/core/shell.rb +15 -9
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +50 -9
- data/lib/deprecated_commands.json +2 -1
- data/lib/generator_templates/controlplane.yml +5 -0
- data/lib/generator_templates/templates/{gvc.yml → app.yml} +4 -4
- data/lib/generator_templates/templates/postgres.yml +1 -1
- data/lib/generator_templates/templates/rails.yml +1 -1
- data/script/check_cpln_links +3 -3
- data/templates/app.yml +18 -0
- data/templates/daily-task.yml +3 -2
- data/templates/rails.yml +3 -2
- data/templates/secrets.yml +11 -0
- data/templates/sidekiq.yml +3 -2
- metadata +38 -25
- data/.rspec +0 -1
- data/lib/command/run_cleanup.rb +0 -116
- data/lib/command/run_detached.rb +0 -175
- data/lib/core/scripts.rb +0 -34
- data/templates/gvc.yml +0 -13
- data/templates/identity.yml +0 -2
data/docs/commands.md
CHANGED
@@ -21,10 +21,14 @@ This `-a` option is used in most of the commands and will pick all other app con
|
|
21
21
|
**Preprocessed template variables:**
|
22
22
|
|
23
23
|
```
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
{{APP_ORG}} - organization name
|
25
|
+
{{APP_NAME}} - GVC/app name
|
26
|
+
{{APP_LOCATION}} - location, per YML file, ENV, or command line arg
|
27
|
+
{{APP_LOCATION_LINK}} - full link for location, ready to be used for the value of `staticPlacement.locationLinks` in the templates
|
28
|
+
{{APP_IMAGE}} - latest app image
|
29
|
+
{{APP_IMAGE_LINK}} - full link for latest app image, ready to be used for the value of `containers[].image` in the templates
|
30
|
+
{{APP_IDENTITY}} - default identity
|
31
|
+
{{APP_IDENTITY_LINK}} - full link for identity, ready to be used for the value of `identityLink` in the templates
|
28
32
|
```
|
29
33
|
|
30
34
|
```sh
|
@@ -32,7 +36,7 @@ APP_IMAGE - will use latest app image
|
|
32
36
|
cpl apply-template redis -a $APP_NAME
|
33
37
|
|
34
38
|
# Applies several templates (practically creating full app).
|
35
|
-
cpl apply-template
|
39
|
+
cpl apply-template app postgres redis rails -a $APP_NAME
|
36
40
|
```
|
37
41
|
|
38
42
|
### `build-image`
|
@@ -101,16 +105,23 @@ cpl copy-image-from-upstream -a $APP_NAME --upstream-token $UPSTREAM_TOKEN --ima
|
|
101
105
|
|
102
106
|
### `delete`
|
103
107
|
|
104
|
-
- Deletes the whole app (GVC with all workloads, all volumesets and all images)
|
108
|
+
- Deletes the whole app (GVC with all workloads, all volumesets and all images) or a specific workload
|
105
109
|
- Will ask for explicit user confirmation
|
106
110
|
|
107
111
|
```sh
|
112
|
+
# Deletes the whole app (GVC with all workloads, all volumesets and all images).
|
108
113
|
cpl delete -a $APP_NAME
|
114
|
+
|
115
|
+
# Deletes a specific workload.
|
116
|
+
cpl delete -a $APP_NAME -w $WORKLOAD_NAME
|
109
117
|
```
|
110
118
|
|
111
119
|
### `deploy-image`
|
112
120
|
|
113
121
|
- Deploys the latest image to app workloads
|
122
|
+
- Optionally runs a release script before deploying if specified through `release_script` in the `.controlplane/controlplane.yml` file and `--run-release-phase` is provided
|
123
|
+
- The release script is run in the context of `cpl run` with the latest image
|
124
|
+
- The deploy will fail if the release script exits with a non-zero code or doesn't exist
|
114
125
|
|
115
126
|
```sh
|
116
127
|
cpl deploy-image -a $APP_NAME
|
@@ -171,6 +182,7 @@ cpl latest-image -a $APP_NAME
|
|
171
182
|
### `logs`
|
172
183
|
|
173
184
|
- Light wrapper to display tailed raw logs for app/workload syntax
|
185
|
+
- Defaults to showing the last 200 entries from the past 1 hour before tailing
|
174
186
|
|
175
187
|
```sh
|
176
188
|
# Displays logs for the default workload (`one_off_workload`).
|
@@ -178,6 +190,15 @@ cpl logs -a $APP_NAME
|
|
178
190
|
|
179
191
|
# Displays logs for a specific workload.
|
180
192
|
cpl logs -a $APP_NAME -w $WORKLOAD_NAME
|
193
|
+
|
194
|
+
# Displays logs for a specific replica of a workload.
|
195
|
+
cpl logs -a $APP_NAME -w $WORKLOAD_NAME -r $REPLICA_NAME
|
196
|
+
|
197
|
+
# Uses a different limit on number of entries.
|
198
|
+
cpl logs -a $APP_NAME --limit 100
|
199
|
+
|
200
|
+
# Uses a different loopback window.
|
201
|
+
cpl logs -a $APP_NAME --since 30min
|
181
202
|
```
|
182
203
|
|
183
204
|
### `maintenance`
|
@@ -251,8 +272,9 @@ cpl open-console -a $APP_NAME
|
|
251
272
|
- Copies the latest image from upstream, runs a release script (optional), and deploys the image
|
252
273
|
- It performs the following steps:
|
253
274
|
- Runs `cpl copy-image-from-upstream` to copy the latest image from upstream
|
254
|
-
- Runs a release script if specified through `release_script` in the `.controlplane/controlplane.yml` file
|
255
275
|
- Runs `cpl deploy-image` to deploy the image
|
276
|
+
- If `.controlplane/controlplane.yml` includes the `release_script`, `cpl deploy-image` will use the `--run-release-phase` option
|
277
|
+
- The deploy will fail if the release script exits with a non-zero code
|
256
278
|
|
257
279
|
```sh
|
258
280
|
cpl promote-app-from-upstream -a $APP_NAME -t $UPSTREAM_TOKEN
|
@@ -304,6 +326,9 @@ cpl ps:stop -a $APP_NAME
|
|
304
326
|
|
305
327
|
# Stops a specific workload in app.
|
306
328
|
cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
|
329
|
+
|
330
|
+
# Stops a specific replica of a workload.
|
331
|
+
cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME -r $REPLICA_NAME
|
307
332
|
```
|
308
333
|
|
309
334
|
### `ps:wait`
|
@@ -320,26 +345,43 @@ cpl ps:swait -a $APP_NAME -w $WORKLOAD_NAME
|
|
320
345
|
|
321
346
|
### `run`
|
322
347
|
|
323
|
-
- Runs one-off
|
324
|
-
- Uses `
|
325
|
-
-
|
326
|
-
|
327
|
-
|
328
|
-
|
348
|
+
- Runs one-off interactive or non-interactive replicas (analog of `heroku run`)
|
349
|
+
- Uses `Cron` workload type and either:
|
350
|
+
- - `cpln workload exec` for interactive mode, with CLI streaming
|
351
|
+
- - log async fetching for non-interactive mode
|
352
|
+
- The Dockerfile entrypoint is used as the command by default, which assumes `exec "${@}"` to be present,
|
353
|
+
and the args ["bash", "-c", cmd_to_run] are passed
|
354
|
+
- The entrypoint can be overriden through `--entrypoint`, which must be a single command or a script path that exists in the container,
|
355
|
+
and the args ["bash", "-c", cmd_to_run] are passed,
|
356
|
+
unless the entrypoint is `bash`, in which case the args ["-c", cmd_to_run] are passed
|
357
|
+
- Providing `--entrypoint none` sets the entrypoint to `bash` by default
|
358
|
+
- If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file,
|
359
|
+
the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
|
329
360
|
|
330
361
|
```sh
|
331
362
|
# Opens shell (bash by default).
|
332
363
|
cpl run -a $APP_NAME
|
333
364
|
|
334
|
-
#
|
335
|
-
cpl run -a $APP_NAME --
|
365
|
+
# Runs interactive command, keeps shell open, and stops job when exiting.
|
366
|
+
cpl run -a $APP_NAME --interactive -- rails c
|
336
367
|
|
337
|
-
#
|
338
|
-
cpl run -a $APP_NAME --
|
339
|
-
cpl run -a $APP_NAME -- rails
|
368
|
+
# Some commands are automatically detected as interactive, so no need to pass `--interactive`.
|
369
|
+
cpl run -a $APP_NAME -- bash
|
370
|
+
cpl run -a $APP_NAME -- rails console
|
371
|
+
cpl run -a $APP_NAME -- rails c
|
372
|
+
cpl run -a $APP_NAME -- rails dbconsole
|
373
|
+
cpl run -a $APP_NAME -- rails db
|
340
374
|
|
341
|
-
# Runs command and
|
342
|
-
cpl run -a $APP_NAME -- rails
|
375
|
+
# Runs non-interactive command, outputs logs, exits with the exit code of the command and stops job.
|
376
|
+
cpl run -a $APP_NAME -- rails db:migrate
|
377
|
+
|
378
|
+
# Runs non-iteractive command, detaches, exits with 0, and prints commands to:
|
379
|
+
# - see logs from the job
|
380
|
+
# - stop the job
|
381
|
+
cpl run -a $APP_NAME --detached -- rails db:migrate
|
382
|
+
|
383
|
+
# The command needs to be quoted if setting an env variable or passing args.
|
384
|
+
cpl run -a $APP_NAME -- 'SOME_ENV_VAR=some_value rails db:migrate'
|
343
385
|
|
344
386
|
# Uses a different image (which may not be promoted yet).
|
345
387
|
cpl run -a $APP_NAME --image appimage:123 -- rails db:migrate # Exact image name
|
@@ -351,47 +393,12 @@ cpl run -a $APP_NAME -w other-workload -- bash
|
|
351
393
|
# Overrides remote CPLN_TOKEN env variable with local token.
|
352
394
|
# Useful when superuser rights are needed in remote container.
|
353
395
|
cpl run -a $APP_NAME --use-local-token -- bash
|
354
|
-
```
|
355
|
-
|
356
|
-
### `run:cleanup`
|
357
|
-
|
358
|
-
- Deletes stale run workloads for an app
|
359
|
-
- Workloads are considered stale based on how many days since created
|
360
|
-
- `stale_run_workload_created_days` in the `.controlplane/controlplane.yml` file specifies the number of days after created that the workload is considered stale
|
361
|
-
- Works for both interactive workloads (created with `cpl run`) and non-interactive workloads (created with `cpl run:detached`)
|
362
|
-
- Will ask for explicit user confirmation of deletion
|
363
|
-
|
364
|
-
```sh
|
365
|
-
cpl run:cleanup -a $APP_NAME
|
366
|
-
```
|
367
|
-
|
368
|
-
### `run:detached`
|
369
|
-
|
370
|
-
- Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)
|
371
|
-
- Uses `Cron` workload type with log async fetching
|
372
|
-
- Implemented with only async execution methods, more suitable for production tasks
|
373
|
-
- Has alternative log fetch implementation with only JSON-polling and no WebSockets
|
374
|
-
- Less responsive but more stable, useful for CI tasks
|
375
|
-
- Deletes the workload whenever finished with success
|
376
|
-
- Deletes the workload whenever finished with failure by default
|
377
|
-
- Use `--no-clean-on-failure` to disable cleanup to help with debugging failed runs
|
378
|
-
|
379
|
-
```sh
|
380
|
-
cpl run:detached rails db:prepare -a $APP_NAME
|
381
396
|
|
382
|
-
#
|
383
|
-
cpl run
|
397
|
+
# Replaces the existing Dockerfile entrypoint with `bash`.
|
398
|
+
cpl run -a $APP_NAME --entrypoint none -- rails db:migrate
|
384
399
|
|
385
|
-
#
|
386
|
-
cpl run
|
387
|
-
cpl run:detached -a $APP_NAME --image latest -- rails db:migrate # Latest sequential image
|
388
|
-
|
389
|
-
# Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
|
390
|
-
cpl run:detached -a $APP_NAME -w other-workload -- rails db:migrate:status
|
391
|
-
|
392
|
-
# Overrides remote CPLN_TOKEN env variable with local token.
|
393
|
-
# Useful when superuser rights are needed in remote container.
|
394
|
-
cpl run:detached -a $APP_NAME --use-local-token -- rails db:migrate:status
|
400
|
+
# Replaces the existing Dockerfile entrypoint.
|
401
|
+
cpl run -a $APP_NAME --entrypoint /app/alternative-entrypoint.sh -- rails db:migrate
|
395
402
|
```
|
396
403
|
|
397
404
|
### `setup-app`
|
@@ -399,6 +406,8 @@ cpl run:detached -a $APP_NAME --use-local-token -- rails db:migrate:status
|
|
399
406
|
- Creates an app and all its workloads
|
400
407
|
- Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
|
401
408
|
- 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)
|
409
|
+
- Automatically binds the app to the secrets policy, as long as both the identity and the policy exist
|
410
|
+
- Use `--skip-secret-access-binding` to prevent the automatic bind
|
402
411
|
|
403
412
|
```sh
|
404
413
|
cpl setup-app -a $APP_NAME
|
data/docs/dns.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# DNS Setup Example
|
2
2
|
|
3
|
+
## Docs
|
4
|
+
|
5
|
+
https://shakadocs.controlplane.com/guides/configure-domain#dns-records
|
6
|
+
|
7
|
+
## Example
|
8
|
+
|
3
9
|
About reactrails.com DNS, steps:
|
4
10
|
1. create CNAME or ALIAS record pointing to rails-xxxx.cpln.app
|
5
11
|
1. go to CPLN Domains -> create
|
data/docs/migrating.md
CHANGED
@@ -36,7 +36,7 @@ key, e.g.:
|
|
36
36
|
my-app-staging:
|
37
37
|
<<: *common
|
38
38
|
setup_app_templates:
|
39
|
-
-
|
39
|
+
- app
|
40
40
|
- redis
|
41
41
|
- memcached
|
42
42
|
- rails
|
@@ -46,8 +46,8 @@ my-app-staging:
|
|
46
46
|
Note how the templates correspond to files in the `.controlplane/templates/` directory. These files will be used by the
|
47
47
|
`cpl setup-app` and `cpl apply-template` commands.
|
48
48
|
|
49
|
-
Ensure that env vars point to the Heroku add-ons in the template for the app (`.controlplane/templates/
|
50
|
-
[this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/templates/
|
49
|
+
Ensure that env vars point to the Heroku add-ons in the template for the app (`.controlplane/templates/app.yml`). See
|
50
|
+
[this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/templates/app.yml).
|
51
51
|
|
52
52
|
After that, create a Dockerfile in `.controlplane/Dockerfile` for your deployment. See
|
53
53
|
[this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/Dockerfile).
|
@@ -61,7 +61,7 @@ app_main_folder/
|
|
61
61
|
controlplane.yml
|
62
62
|
entrypoint.sh # App-specific - edit as needed.
|
63
63
|
templates/
|
64
|
-
|
64
|
+
app.yml
|
65
65
|
memcached.yml
|
66
66
|
rails.yml
|
67
67
|
redis.yml
|
@@ -93,7 +93,7 @@ cpl setup-app -a my-app-staging
|
|
93
93
|
cpl build-image -a my-app-staging --commit 456
|
94
94
|
|
95
95
|
# Prepare database.
|
96
|
-
cpl run
|
96
|
+
cpl run -a my-app-staging --image latest -- rails db:prepare
|
97
97
|
|
98
98
|
# Deploy latest image.
|
99
99
|
cpl deploy-image -a my-app-staging
|
@@ -113,7 +113,7 @@ cpl build-image -a my-app-staging --commit ABC
|
|
113
113
|
|
114
114
|
# Run database migrations (or other release tasks) with latest image, while app is still running on previous image.
|
115
115
|
# This is analogous to the release phase.
|
116
|
-
cpl run
|
116
|
+
cpl run -a my-app-staging --image latest -- rails db:migrate
|
117
117
|
|
118
118
|
# Deploy latest image.
|
119
119
|
cpl deploy-image -a my-app-staging
|
@@ -192,7 +192,7 @@ configure an entry for, e.g., `my-app-review`, and then create review apps start
|
|
192
192
|
<<: *common
|
193
193
|
match_if_app_name_starts_with: true
|
194
194
|
setup_app_templates:
|
195
|
-
-
|
195
|
+
- app
|
196
196
|
- redis
|
197
197
|
- memcached
|
198
198
|
- rails
|
@@ -215,9 +215,9 @@ fi
|
|
215
215
|
|
216
216
|
# The `NEW_APP` env var that we exported above can be used to either reset or migrate the database before deploying.
|
217
217
|
if [ -n "${NEW_APP}" ]; then
|
218
|
-
cpl run
|
218
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:reset
|
219
219
|
else
|
220
|
-
cpl run
|
220
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:migrate
|
221
221
|
fi
|
222
222
|
```
|
223
223
|
|
@@ -226,7 +226,7 @@ Then follow the same steps for the initial deployment or code upgrades.
|
|
226
226
|
### Database for Review Apps
|
227
227
|
|
228
228
|
For the review app resources, these should be handled as env vars in the template for the app
|
229
|
-
(`.controlplane/templates/
|
229
|
+
(`.controlplane/templates/app.yml`), .e.g.:
|
230
230
|
|
231
231
|
```yaml
|
232
232
|
- name: DATABASE_URL
|
data/docs/tips.md
CHANGED
@@ -65,7 +65,7 @@ The actual remote IP of the workload container is in the 127.0.0.x network, so t
|
|
65
65
|
`REMOTE_ADDR` env var.
|
66
66
|
|
67
67
|
However, Control Plane additionally sets the `x-forwarded-for` and `x-envoy-external-address` headers (and others - see:
|
68
|
-
https://
|
68
|
+
https://shakadocs.controlplane.com/concepts/security#headers). On Rails, the `ActionDispatch::RemoteIp` middleware should
|
69
69
|
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`.
|
@@ -85,9 +85,21 @@ For storing ENVs in the source code, we can use a level of indirection so that y
|
|
85
85
|
code like `cpln://secret/my-app-review-env-secrets.SECRET_KEY_BASE` and then have the secret value stored at the org
|
86
86
|
level, which applies to your GVCs mapped to that org.
|
87
87
|
|
88
|
-
|
88
|
+
You can do this during the initial app setup, like this:
|
89
89
|
|
90
|
-
1.
|
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"
|
91
103
|
2. Create a secret with `Secret Type: Dictionary` (e.g., `my-secrets`) and add the secret env vars there
|
92
104
|
3. In the upper left "Manage GVC" menu, click on "Identities"
|
93
105
|
4. Create an identity (e.g., `my-identity`)
|
data/examples/circleci.yml
CHANGED
@@ -27,7 +27,7 @@ build-staging:
|
|
27
27
|
command: cpl build-image -a ${APP_NAME}
|
28
28
|
- run:
|
29
29
|
name: Database tasks
|
30
|
-
command: cpl run
|
30
|
+
command: cpl run -a ${APP_NAME} --image latest -- rails db:migrate
|
31
31
|
- run:
|
32
32
|
name: Deploy image
|
33
33
|
command: cpl deploy-image -a ${APP_NAME}
|
@@ -75,9 +75,9 @@ build-review-app:
|
|
75
75
|
name: Database tasks
|
76
76
|
command: |
|
77
77
|
if [ -n "${NEW_APP}" ]; then
|
78
|
-
cpl run
|
78
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:reset
|
79
79
|
else
|
80
|
-
cpl run
|
80
|
+
cpl run -a ${APP_NAME} --image latest -- rails db:migrate
|
81
81
|
fi
|
82
82
|
- run:
|
83
83
|
name: Deploy image
|
data/examples/controlplane.yml
CHANGED
@@ -17,31 +17,61 @@ aliases:
|
|
17
17
|
|
18
18
|
# Control Plane offers the ability to use multiple locations.
|
19
19
|
# default_location is used for commands that require a location
|
20
|
-
# including `ps`, `run`, `
|
20
|
+
# including `ps`, `run`, `apply-template`.
|
21
21
|
# This can be overridden with option --location=<location> and
|
22
22
|
# CPLN_LOCATION environment variable.
|
23
23
|
# TODO: Allow specification of multiple locations.
|
24
24
|
default_location: aws-us-east-2
|
25
25
|
|
26
26
|
# Allows running the command `cpl setup-app`
|
27
|
-
# instead of `cpl apply-template
|
28
|
-
|
29
|
-
|
27
|
+
# instead of `cpl apply-template app redis postgres memcached rails sidekiq`.
|
28
|
+
#
|
29
|
+
# Note:
|
30
|
+
# 1. These names correspond to files in the `./controlplane/templates` directory.
|
31
|
+
# 2. Each file can contain many objects, such as in the case of templates that create a resource, like `postgres`.
|
32
|
+
# 3. While the naming often corresponds to a workload or other object name, the naming is arbitrary.
|
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
|
+
setup_app_templates:
|
38
|
+
- app
|
30
39
|
- redis
|
31
40
|
- postgres
|
32
41
|
- memcached
|
33
42
|
- rails
|
34
43
|
- sidekiq
|
35
44
|
|
45
|
+
# Only needed if using a custom secrets name.
|
46
|
+
# The default is '{APP_PREFIX}-secrets'. For example:
|
47
|
+
# - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
|
48
|
+
# it would be 'my-app-staging-secrets'
|
49
|
+
# - for an app 'my-app-review-1234' with `match_if_app_name_starts_with` set to `true`,
|
50
|
+
# it would be 'my-app-review-secrets'
|
51
|
+
secrets_name: my-secrets
|
52
|
+
|
53
|
+
# Only needed if using a custom secrets policy name.
|
54
|
+
# The default is '{APP_SECRETS}-policy'. For example:
|
55
|
+
# - for an app 'my-app-staging' with `match_if_app_name_starts_with` set to `false`,
|
56
|
+
# it would be 'my-app-staging-secrets-policy'
|
57
|
+
# - for an app 'my-app-review-1234' with `match_if_app_name_starts_with` set to `true`,
|
58
|
+
# it would be 'my-app-review-secrets-policy'
|
59
|
+
secrets_policy_name: my-secrets-policy
|
60
|
+
|
36
61
|
# Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
|
37
62
|
one_off_workload: rails
|
38
63
|
|
39
64
|
# Workloads that are for the application itself and are using application Docker images.
|
65
|
+
# These are updated with the new image when running the `deploy-image` command,
|
66
|
+
# and are also used by the `info` and `ps:` commands in order to get all of the defined workloads.
|
67
|
+
# On the other hand, if you have a workload for Redis, that would NOT use the application Docker image
|
68
|
+
# and not be listed here.
|
40
69
|
app_workloads:
|
41
70
|
- rails
|
42
71
|
- sidekiq
|
43
72
|
|
44
73
|
# Additional "service type" workloads, using non-application Docker images.
|
74
|
+
# These are only used by the `info` and `ps:` commands in order to get all of the defined workloads.
|
45
75
|
additional_workloads:
|
46
76
|
- redis
|
47
77
|
- postgres
|
@@ -51,7 +81,7 @@ aliases:
|
|
51
81
|
maintenance_workload: maintenance
|
52
82
|
|
53
83
|
# Fixes the remote terminal size to match the local terminal size
|
54
|
-
# when running
|
84
|
+
# when running `cpl run`.
|
55
85
|
fix_terminal_size: true
|
56
86
|
|
57
87
|
# Apps with a deployed image created before this amount of days will be listed for deletion
|
@@ -66,10 +96,6 @@ aliases:
|
|
66
96
|
# when running the command `cpl cleanup-images` (`image_retention_max_qty` takes precedence).
|
67
97
|
image_retention_days: 5
|
68
98
|
|
69
|
-
# Run workloads created before this amount of days will be listed for deletion
|
70
|
-
# when running the command `cpl run:cleanup`.
|
71
|
-
stale_run_workload_created_days: 2
|
72
|
-
|
73
99
|
apps:
|
74
100
|
my-app-staging:
|
75
101
|
# Use the values from the common section above.
|
@@ -20,10 +20,14 @@ module Command
|
|
20
20
|
**Preprocessed template variables:**
|
21
21
|
|
22
22
|
```
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
{{APP_ORG}} - organization name
|
24
|
+
{{APP_NAME}} - GVC/app name
|
25
|
+
{{APP_LOCATION}} - location, per YML file, ENV, or command line arg
|
26
|
+
{{APP_LOCATION_LINK}} - full link for location, ready to be used for the value of `staticPlacement.locationLinks` in the templates
|
27
|
+
{{APP_IMAGE}} - latest app image
|
28
|
+
{{APP_IMAGE_LINK}} - full link for latest app image, ready to be used for the value of `containers[].image` in the templates
|
29
|
+
{{APP_IDENTITY}} - default identity
|
30
|
+
{{APP_IDENTITY_LINK}} - full link for identity, ready to be used for the value of `identityLink` in the templates
|
27
31
|
```
|
28
32
|
DESC
|
29
33
|
EXAMPLES = <<~EX
|
@@ -32,11 +36,11 @@ module Command
|
|
32
36
|
cpl apply-template redis -a $APP_NAME
|
33
37
|
|
34
38
|
# Applies several templates (practically creating full app).
|
35
|
-
cpl apply-template
|
39
|
+
cpl apply-template app postgres redis rails -a $APP_NAME
|
36
40
|
```
|
37
41
|
EX
|
38
42
|
|
39
|
-
def call # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
43
|
+
def call # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
40
44
|
ensure_templates!
|
41
45
|
|
42
46
|
@created_items = []
|
@@ -46,7 +50,7 @@ module Command
|
|
46
50
|
@asked_for_confirmation = false
|
47
51
|
|
48
52
|
pending_templates = templates.select do |template|
|
49
|
-
if template == "
|
53
|
+
if template == "app"
|
50
54
|
confirm_app(template)
|
51
55
|
else
|
52
56
|
confirm_workload(template)
|
@@ -55,24 +59,30 @@ module Command
|
|
55
59
|
|
56
60
|
progress.puts if @asked_for_confirmation
|
57
61
|
|
62
|
+
@deprecated_variables = []
|
63
|
+
|
58
64
|
pending_templates.each do |template, filename|
|
59
65
|
step("Applying template '#{template}'", abort_on_error: false) do
|
60
66
|
items = apply_template(filename)
|
61
|
-
|
62
|
-
items.each do |item|
|
63
|
-
report_success(item)
|
64
|
-
end
|
65
|
-
else
|
67
|
+
unless items
|
66
68
|
report_failure(template)
|
69
|
+
next false
|
67
70
|
end
|
68
71
|
|
69
|
-
|
72
|
+
items.each do |item|
|
73
|
+
report_success(item)
|
74
|
+
end
|
75
|
+
true
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
79
|
+
warn_deprecated_variables
|
80
|
+
|
73
81
|
print_created_items
|
74
82
|
print_failed_templates
|
75
83
|
print_skipped_templates
|
84
|
+
|
85
|
+
exit(ExitCode::ERROR_DEFAULT) if @failed_templates.any?
|
76
86
|
end
|
77
87
|
|
78
88
|
private
|
@@ -124,17 +134,55 @@ module Command
|
|
124
134
|
false
|
125
135
|
end
|
126
136
|
|
127
|
-
def apply_template(filename)
|
137
|
+
def apply_template(filename) # rubocop:disable Metrics/MethodLength
|
128
138
|
data = File.read(filename)
|
129
|
-
.gsub("
|
130
|
-
.gsub("
|
131
|
-
.gsub("
|
132
|
-
.gsub("
|
139
|
+
.gsub("{{APP_ORG}}", config.org)
|
140
|
+
.gsub("{{APP_NAME}}", config.app)
|
141
|
+
.gsub("{{APP_LOCATION}}", config.location)
|
142
|
+
.gsub("{{APP_LOCATION_LINK}}", app_location_link)
|
143
|
+
.gsub("{{APP_IMAGE}}", latest_image)
|
144
|
+
.gsub("{{APP_IMAGE_LINK}}", app_image_link)
|
145
|
+
.gsub("{{APP_IDENTITY}}", app_identity)
|
146
|
+
.gsub("{{APP_IDENTITY_LINK}}", app_identity_link)
|
147
|
+
.gsub("{{APP_SECRETS}}", app_secrets)
|
148
|
+
.gsub("{{APP_SECRETS_POLICY}}", app_secrets_policy)
|
149
|
+
|
150
|
+
find_deprecated_variables(data)
|
151
|
+
|
152
|
+
# Kept for backwards compatibility
|
153
|
+
data = data
|
154
|
+
.gsub("APP_ORG", config.org)
|
155
|
+
.gsub("APP_GVC", config.app)
|
156
|
+
.gsub("APP_LOCATION", config.location)
|
157
|
+
.gsub("APP_IMAGE", latest_image)
|
133
158
|
|
134
159
|
# Don't read in YAML.safe_load as that doesn't handle multiple documents
|
135
160
|
cp.apply_template(data)
|
136
161
|
end
|
137
162
|
|
163
|
+
def new_variables
|
164
|
+
{
|
165
|
+
"APP_ORG" => "{{APP_ORG}}",
|
166
|
+
"APP_GVC" => "{{APP_NAME}}",
|
167
|
+
"APP_LOCATION" => "{{APP_LOCATION}}",
|
168
|
+
"APP_IMAGE" => "{{APP_IMAGE}}"
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def find_deprecated_variables(data)
|
173
|
+
@deprecated_variables.push(*new_variables.keys.select { |old_key| data.include?(old_key) })
|
174
|
+
@deprecated_variables = @deprecated_variables.uniq.sort
|
175
|
+
end
|
176
|
+
|
177
|
+
def warn_deprecated_variables
|
178
|
+
return unless @deprecated_variables.any?
|
179
|
+
|
180
|
+
message = "Please replace these variables in the templates, " \
|
181
|
+
"as support for them will be removed in a future major version bump:"
|
182
|
+
deprecated = @deprecated_variables.map { |old_key| " - #{old_key} -> #{new_variables[old_key]}" }.join("\n")
|
183
|
+
progress.puts("\n#{Shell.color("DEPRECATED: #{message}", :yellow)}\n#{deprecated}")
|
184
|
+
end
|
185
|
+
|
138
186
|
def report_success(item)
|
139
187
|
@created_items.push(item)
|
140
188
|
end
|