cpl 0.1.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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +60 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +16 -0
  6. data/CHANGELOG.md +5 -0
  7. data/CONTRIBUTING.md +12 -0
  8. data/Gemfile +7 -0
  9. data/Gemfile.lock +104 -0
  10. data/LICENSE +21 -0
  11. data/README.md +318 -0
  12. data/Rakefile +11 -0
  13. data/bin/cpl +6 -0
  14. data/cpl +15 -0
  15. data/cpl.gemspec +42 -0
  16. data/docs/commands.md +219 -0
  17. data/docs/troubleshooting.md +6 -0
  18. data/examples/circleci.yml +106 -0
  19. data/examples/controlplane.yml +44 -0
  20. data/lib/command/base.rb +177 -0
  21. data/lib/command/build_image.rb +25 -0
  22. data/lib/command/config.rb +33 -0
  23. data/lib/command/delete.rb +50 -0
  24. data/lib/command/env.rb +21 -0
  25. data/lib/command/exists.rb +23 -0
  26. data/lib/command/latest_image.rb +18 -0
  27. data/lib/command/logs.rb +29 -0
  28. data/lib/command/open.rb +33 -0
  29. data/lib/command/promote_image.rb +27 -0
  30. data/lib/command/ps.rb +40 -0
  31. data/lib/command/ps_restart.rb +34 -0
  32. data/lib/command/ps_start.rb +34 -0
  33. data/lib/command/ps_stop.rb +34 -0
  34. data/lib/command/run.rb +106 -0
  35. data/lib/command/run_detached.rb +148 -0
  36. data/lib/command/setup.rb +59 -0
  37. data/lib/command/test.rb +26 -0
  38. data/lib/core/config.rb +81 -0
  39. data/lib/core/controlplane.rb +128 -0
  40. data/lib/core/controlplane_api.rb +51 -0
  41. data/lib/core/controlplane_api_cli.rb +10 -0
  42. data/lib/core/controlplane_api_direct.rb +42 -0
  43. data/lib/core/scripts.rb +34 -0
  44. data/lib/cpl/version.rb +5 -0
  45. data/lib/cpl.rb +139 -0
  46. data/lib/main.rb +5 -0
  47. data/postgres.md +436 -0
  48. data/redis.md +112 -0
  49. data/script/generate_commands_docs +60 -0
  50. data/templates/gvc.yml +13 -0
  51. data/templates/identity.yml +2 -0
  52. data/templates/memcached.yml +23 -0
  53. data/templates/postgres.yml +31 -0
  54. data/templates/rails.yml +25 -0
  55. data/templates/redis.yml +20 -0
  56. data/templates/sidekiq.yml +28 -0
  57. metadata +312 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2392653f1a75e0dc398590cc5c0e9d89d4769a50af3432b2861e01ff794e8cda
4
+ data.tar.gz: 13c33cc6465394b90b1fd8e94f711c98135bfdcb25756db7d3b7b0c8bfc819fa
5
+ SHA512:
6
+ metadata.gz: bc2b5f2555b8f329ad8d5b2be9f5762e6f265f499baaa035e65c24257b47c26459842f2611ee8d352af65b3dcabf4f0e6570007c59f5ca543f3edb382ed04747
7
+ data.tar.gz: 904028e00550311c8b9327fb3a17a8a00c75b4806e81ca8359d5b3f6ae55b19f8a89efbc3ccc087e4f62e2243930587df1f693ebbbac9470377b0e6905e0dd19
@@ -0,0 +1,60 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ rubocop:
11
+ runs-on: ubuntu-latest
12
+ name: Rubocop
13
+ strategy:
14
+ matrix:
15
+ ruby:
16
+ - "2.7"
17
+ - "3.0"
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v3
21
+ - name: Set up Ruby
22
+ uses: ruby/setup-ruby@v1
23
+ with:
24
+ ruby-version: ${{ matrix.ruby }}
25
+ rubygems: latest
26
+ - name: Install dependencies
27
+ run: bundle install
28
+ - name: Analyze code
29
+ run: bundle exec rubocop
30
+
31
+ rspec:
32
+ needs: rubocop
33
+ runs-on: ubuntu-latest
34
+ name: RSpec
35
+ env:
36
+ RAILS_ENV: test
37
+ strategy:
38
+ matrix:
39
+ ruby:
40
+ - "2.7"
41
+ - "3.0"
42
+ steps:
43
+ - name: Checkout code
44
+ uses: actions/checkout@v3
45
+ - name: Set up Ruby
46
+ uses: ruby/setup-ruby@v1
47
+ with:
48
+ ruby-version: ${{ matrix.ruby }}
49
+ rubygems: latest
50
+ bundler-cache: false
51
+ - name: Install dependencies
52
+ run: bundle install
53
+ - name: Run tests
54
+ run: bundle exec rspec spec
55
+ - name: Upload coverage results
56
+ uses: actions/upload-artifact@master
57
+ if: always()
58
+ with:
59
+ name: coverage-report
60
+ path: coverage
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ .env
2
+ .DS_Store
3
+
4
+ /.bundle/
5
+ /.yardoc
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
12
+
13
+ # rspec failure tracking
14
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.7
7
+ NewCops: enable
8
+
9
+ Metrics/AbcSize:
10
+ Enabled: false
11
+
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ Style/StringLiterals:
16
+ EnforcedStyle: double_quotes
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2023-02-08
4
+
5
+ - Initial release
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,12 @@
1
+ # Contributing
2
+
3
+ ## Linting
4
+ Be sure to run `rubocop -a` before committing code.
5
+
6
+ ## Debugging
7
+
8
+ 1. Install gem: `gem install debug`
9
+ 2. Require: Add a `require "debug"` statement to the file you want to debug.
10
+ 3. Add breakpoint: Add a `debugger` statement to the line you want to debug.
11
+ 4. Modify the `lib/command/test.rb` file to triggger the code that you want to run.
12
+ 5. Run the test in your test app with a `.controlplane` directory. `cpl test -a my-app-name`
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ gem "rake", "~> 13.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,104 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cpl (0.1.0)
5
+ cgi (~> 0.3.6)
6
+ debug (~> 1.7.1)
7
+ dotenv (~> 2.8.1)
8
+ json (~> 2.6.3)
9
+ net-http (~> 0.3.2)
10
+ pathname (~> 0.2.1)
11
+ psych (~> 5.1.0)
12
+ tempfile (~> 0.1.3)
13
+ thor (~> 1.2.1)
14
+ yaml (~> 0.2.1)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ ast (2.4.2)
20
+ cgi (0.3.6)
21
+ debug (1.7.1)
22
+ irb (>= 1.5.0)
23
+ reline (>= 0.3.1)
24
+ diff-lcs (1.5.0)
25
+ docile (1.4.0)
26
+ dotenv (2.8.1)
27
+ io-console (0.6.0)
28
+ irb (1.6.2)
29
+ reline (>= 0.3.0)
30
+ json (2.6.3)
31
+ net-http (0.3.2)
32
+ uri
33
+ parallel (1.22.1)
34
+ parser (3.2.0.0)
35
+ ast (~> 2.4.1)
36
+ pathname (0.2.1)
37
+ psych (5.1.0)
38
+ stringio
39
+ rainbow (3.1.1)
40
+ rake (13.0.6)
41
+ regexp_parser (2.6.2)
42
+ reline (0.3.2)
43
+ io-console (~> 0.5)
44
+ rexml (3.2.5)
45
+ rspec (3.12.0)
46
+ rspec-core (~> 3.12.0)
47
+ rspec-expectations (~> 3.12.0)
48
+ rspec-mocks (~> 3.12.0)
49
+ rspec-core (3.12.1)
50
+ rspec-support (~> 3.12.0)
51
+ rspec-expectations (3.12.2)
52
+ diff-lcs (>= 1.2.0, < 2.0)
53
+ rspec-support (~> 3.12.0)
54
+ rspec-mocks (3.12.3)
55
+ diff-lcs (>= 1.2.0, < 2.0)
56
+ rspec-support (~> 3.12.0)
57
+ rspec-support (3.12.0)
58
+ rubocop (1.45.0)
59
+ json (~> 2.3)
60
+ parallel (~> 1.10)
61
+ parser (>= 3.2.0.0)
62
+ rainbow (>= 2.2.2, < 4.0)
63
+ regexp_parser (>= 1.8, < 3.0)
64
+ rexml (>= 3.2.5, < 4.0)
65
+ rubocop-ast (>= 1.24.1, < 2.0)
66
+ ruby-progressbar (~> 1.7)
67
+ unicode-display_width (>= 2.4.0, < 3.0)
68
+ rubocop-ast (1.24.1)
69
+ parser (>= 3.1.1.0)
70
+ rubocop-capybara (2.17.0)
71
+ rubocop (~> 1.41)
72
+ rubocop-rake (0.6.0)
73
+ rubocop (~> 1.0)
74
+ rubocop-rspec (2.18.1)
75
+ rubocop (~> 1.33)
76
+ rubocop-capybara (~> 2.17)
77
+ ruby-progressbar (1.11.0)
78
+ simplecov (0.22.0)
79
+ docile (~> 1.1)
80
+ simplecov-html (~> 0.11)
81
+ simplecov_json_formatter (~> 0.1)
82
+ simplecov-html (0.12.3)
83
+ simplecov_json_formatter (0.1.4)
84
+ stringio (3.0.5)
85
+ tempfile (0.1.3)
86
+ thor (1.2.1)
87
+ unicode-display_width (2.4.2)
88
+ uri (0.12.0)
89
+ yaml (0.2.1)
90
+
91
+ PLATFORMS
92
+ x86_64-linux
93
+
94
+ DEPENDENCIES
95
+ cpl!
96
+ rake (~> 13.0)
97
+ rspec (~> 3.12.0)
98
+ rubocop (~> 1.45.0)
99
+ rubocop-rake (~> 0.6.0)
100
+ rubocop-rspec (~> 2.18.1)
101
+ simplecov (~> 0.22.0)
102
+
103
+ BUNDLED WITH
104
+ 2.4.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 ShakaCode
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,318 @@
1
+ # Heroku to Control Plane
2
+
3
+ _A playbook for migrating from [Heroku](https://heroku.com) to [Control Plane](https://controlplane.com)_
4
+
5
+ This playbook shows how to move "Heroku apps" to "Control Plane workloads" via an open-source `cpl` CLI on top of Control Plane's `cpln` CLI.
6
+
7
+ Heroku provides a UX and CLI that enables easy publishing of Ruby on Rails and other apps. This ease of use comes via many "Heroku" abstractions and naming conventions.
8
+ Control Plane, on the other hand, gives you access to raw cloud computing power. However, you need to know precisely how to use it.
9
+
10
+ To simplify migration to and usage of Control Plane for Heroku users, this repository provides a **concept mapping** and a **helper CLI** based on templates to save lots of day-to-day typing (and human errors).
11
+
12
+ 1. [Key features](#key-features)
13
+ 2. [Concept mapping](#concept-mapping)
14
+ 3. [Installation](#installation)
15
+ 4. [Example CLI flow for application build/deployment](#example-cli-flow-for-application-builddeployment)
16
+ 5. [Example project modifications for Control Plane](#example-project-modifications-for-control-plane)
17
+ 6. [Environment](#environment)
18
+ 7. [Database](#database)
19
+ 8. [In-memory databases](#in-memory-databases)
20
+ 9. [CLI commands reference](#cli-commands-reference)
21
+ 10. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
22
+ 11. [Examples](#examples)
23
+ 12. [Migrating Postgres database from Heroku infrastructure](/postgres.md)
24
+ 13. [Migrating Redis database from Heroku infrastructure](/redis.md)
25
+
26
+ ## Key features
27
+
28
+ - A `cpl` command to complement the default Control Plane `cpln` command with "Heroku style scripting." The Ruby source can serve as inspiration for your own scripts.
29
+ - Easy to understand Heroku to Control Plane conventions in setup and naming.
30
+ - **Safe, production-ready** equivalents of `heroku run` and `heroku run:detached` for Control Plane.
31
+ - Automatic sequential release tagging for Docker images.
32
+ - A project-aware CLI which enables working on multiple projects.
33
+
34
+ ## Concept mapping
35
+
36
+ On Heroku, everything runs as an app, which means an entity that:
37
+
38
+ 1. Runs code from a Git repo
39
+ 2. Runs several process types, as defined in the `Procfile`
40
+ 3. Has dynos, which are Linux containers that run these process types
41
+ 4. Has add-ons, including the database and other services
42
+ 5. Has common environment variables
43
+
44
+ On Control Plane, we can map a Heroku app to a GVC (Global Virtual Cloud). Such a cloud consists of workloads, which can be anything that can run as a container.
45
+
46
+ **Mapping of Concepts:**
47
+
48
+ | Heroku | Control Plane |
49
+ | ---------------- | ------------------------------------------- |
50
+ | _app_ | _GVC_ (Global Virtual Cloud) |
51
+ | _dyno_ | _workload_ |
52
+ | _add-on_ | either a _workload_ or an external resource |
53
+ | _review app_ | _GVC (app)_ in staging _organization_ |
54
+ | _staging env_ | _GVC (app)_ in staging _organization_ |
55
+ | _production env_ | _GVC (app)_ in production _organization_ |
56
+
57
+ On Heroku, dyno types are specified in the `Procfile` and configured via the CLI/UI; add-ons are configured only via the CLI/UI.
58
+ On Control Plane, workloads are created either by _templates_ (preferred way) or via the CLI/UI.
59
+
60
+ For the typical Rails app, this means:
61
+
62
+ | Function | Examples | On Heroku | On Control Plane |
63
+ | ----------------- | -------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |
64
+ | web traffic | `rails`, `sinatra` | `web` dyno | workload with app image |
65
+ | background jobs | `sidekiq`, `resque` | `worker` dyno | workload with app image |
66
+ | db | `postgres`, `mysql` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
67
+ | in-memory db | `redis`, `memcached` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
68
+ | special something | `mailtrap` | add-on | external provider or can be set up for development/testing with Docker image (lacks persistence between restarts) |
69
+
70
+ ## Installation
71
+
72
+ **Note:** `cpl` CLI is configured via a local clone clone of this repo. We may publish it later as a Ruby gem or Node package.
73
+
74
+ 1. Install `node` (required for Control Plane CLI).
75
+ 2. Install `ruby` (required for these helpers).
76
+ 3. Install Control Plane CLI (adds `cpln` command) and configure credentials.
77
+
78
+ ```sh
79
+ npm install -g @controlplane/cli
80
+ cpln login
81
+ ```
82
+
83
+ 4. Install this repo locally and alias `cpl` command globally for easier access, e.g.:
84
+
85
+ ```sh
86
+ git clone https://github.com/shakacode/heroku-to-control-plane
87
+
88
+ # Create an alias in some local shell startup script, e.g., `.profile`, `.bashrc`, etc.
89
+ alias cpl="~/projects/heroku-to-control-plane/cpl"
90
+ ```
91
+
92
+ - For each Git project that you want to deploy to Control Plane, copy project-specific configs to a `.controlplane` directory at the top of your project. `cpl` will pick those up depending on which project
93
+ folder tree it runs. Thus, this automates running several projects with different configs without explicitly switching configs.
94
+
95
+ 5. Create a `Dockerfile` for your production deployment. See [this example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/Dockerfile).
96
+
97
+ ## Example CLI flow for application build/deployment
98
+
99
+ **Notes:**
100
+
101
+ 1. `myapp` is an app name defined in the `.controlplane/controlplane.yml` file, such as `ror-tutorial` in [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
102
+ 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup` command.
103
+
104
+ ```sh
105
+ # Provision infrastructure (one-time-only for new apps) using templates.
106
+ # Note how the arguments correspond to files in the `.controlplane/templates` directory.
107
+ cpl setup gvc postgres redis memcached rails sidekiq -a myapp
108
+
109
+ # Build and push image with auto-tagging "myapp:1_456".
110
+ cpl build-image -a myapp --commit 456
111
+
112
+ # Prepare database.
113
+ cpl run:detached rails db:prepare -a myapp --image latest
114
+
115
+ # Promote latest image.
116
+ cpl promote-image -a myapp
117
+
118
+ # Open app in browser.
119
+ cpl open -a myapp
120
+ ```
121
+
122
+ ## Example project modifications for Control Plane
123
+
124
+ _See this for a complete example._
125
+
126
+ To learn how to migrate an app, we recommend that you first follow along with [this example project](https://github.com/shakacode/react-webpack-rails-tutorial).
127
+
128
+ 1. Create the `.controlplane` directory at the top of your project and copy files from the `templates` directory of this repo to
129
+ something as follows:
130
+
131
+ ```sh
132
+ app_main_folder/
133
+ .controlplane/
134
+ Dockerfile # Your app's Dockerfile, with some Control Plane changes.
135
+ controlplane.yml
136
+ entrypoint.sh # App-specific, edit as needed.
137
+ templates/
138
+ gvc.yml
139
+ memcached.yml
140
+ postgres.yml
141
+ rails.yml
142
+ redis.yml
143
+ sidekiq.yml
144
+ ```
145
+
146
+ The example [`.controlplane` directory](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane) already contains these files.
147
+
148
+ 2. Edit your `controlplane.yml` file as needed. For example, see [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
149
+
150
+ ```yaml
151
+ # Keys beginning with "cpln_" correspond to your settings in Control Plane.
152
+
153
+ aliases:
154
+ common: &common
155
+ # Organization name for staging (customize to your needs).
156
+ # Production apps will use a different Control Plane organization, specified below, for security.
157
+ cpln_org: my-org-staging
158
+
159
+ # Example apps use only one location. Control Plane offers the ability to use multiple locations.
160
+ # TODO -- allow specification of multiple locations
161
+ default_location: aws-us-east-2
162
+
163
+ # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
164
+ one_off_workload: rails
165
+
166
+ # Workloads that are for the application itself and are using application Docker images.
167
+ app_workloads:
168
+ - rails
169
+ - sidekiq
170
+
171
+ # Additional "service type" workloads, using non-application Docker images.
172
+ additional_workloads:
173
+ - redis
174
+ - postgres
175
+ - memcached
176
+
177
+ apps:
178
+ my-app-staging:
179
+ # Use the values from the common section above.
180
+ <<: *common
181
+ my-app-review:
182
+ <<: *common
183
+ # If `match_if_app_name_starts_with` == `true`, then use this config for app names starting with this name,
184
+ # e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
185
+ match_if_app_name_starts_with: true
186
+ my-app-production:
187
+ <<: *common
188
+ # Use a different organization for production.
189
+ cpln_org: my-org-production
190
+ # Allows running the command `cpl pipeline-promote my-app-staging` to promote the staging app to production.
191
+ upstream: my-app-staging
192
+ my-app-other:
193
+ <<: *common
194
+ # You can specify a different `Dockerfile` relative to the `.controlplane` directory (default is just "Dockerfile").
195
+ dockerfile: ../some_other/Dockerfile
196
+ ```
197
+
198
+ 3. We recommend that you try out the commands listed in [the example](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/readme.md). These steps will guide you through:
199
+ 1. Provision the GVC and workloads
200
+ 2. Build the Docker image
201
+ 3. Run Rails migrations, like in the Heroku release phase
202
+ 4. Promote the lastest Docker image
203
+
204
+ ## Environment
205
+
206
+ There are two main places where we can set up environment variables in Control Plane:
207
+
208
+ - **In `workload/container/env`** - those are container-specific and need to be set up individually for each container.
209
+
210
+ - **In `gvc/env`** - this is a "common" place to keep env vars which we can share among different workloads.
211
+ Those common variables are not visible by default, and we should explicitly enable them via the `inheritEnv` property.
212
+
213
+ In general, `gvc/env` vars are useful for "app" types of workloads, e.g., `rails`, `sidekiq`, as they can easily share
214
+ common configs (the same way as on a Heroku app). They are not needed for non-app workloads,
215
+ e.g., `redis`, `memcached`.
216
+
217
+ It is ok to keep most of the environment variables for non-production environments in the app templates as, in general,
218
+ they are not secret and can be committed to the repository.
219
+
220
+ It is also possible to set up a Secret store (of type Dictionary), which we can reference as,
221
+ e.g., `cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_VAR_NAME`.
222
+ In such a case, we also need to set up an app Identity and proper Policy to access the secret.
223
+
224
+ ```yaml
225
+ # In `templates/gvc.yml`:
226
+ spec:
227
+ env:
228
+ - name: MY_GLOBAL_VAR
229
+ value: 'value'
230
+ - name: MY_SECRET_GLOBAL_VAR
231
+ value: 'cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_GLOBAL_VAR'
232
+
233
+ # In `templates/rails.yml`:
234
+ spec:
235
+ containers:
236
+ - name: rails
237
+ env:
238
+ - name: MY_LOCAL_VAR
239
+ value: 'value'
240
+ - name: MY_SECRET_LOCAL_VAR
241
+ value: 'cpln://secret/MY_SECRET_STORE_NAME/MY_SECRET_LOCAL_VAR'
242
+ inheritEnv: true # To enable global env inheritance
243
+ ```
244
+
245
+ ## Database
246
+
247
+ There are several options for a database setup on Control Plane:
248
+
249
+ 1. **Heroku Postgres**. It is the least recommended but simplest. We only need to provision the Postgres add-on on Heroku and
250
+ copy its `XXXXXX_URL` connection string. This is good for quick testing, but unsuitable for the long term.
251
+
252
+ 2. **Control Plane container**. We can set it up as a workload using one of the default [Docker Hub](https://hub.docker.com/) images.
253
+ However, such a setup lacks persistence between container restarts.
254
+ We can use this only for an example or test app
255
+ where the database doesn't keep any serious data and where such data is restorable.
256
+
257
+ 3. Any other cloud provider for Postgres, e.g., Amazon's RDS can be a quick go-to. Here are [instructions for setting up a free tier of RDS.](https://aws.amazon.com/premiumsupport/knowledge-center/free-tier-rds-launch/).
258
+
259
+ **Tip:** If you are using RDS for development/testing purposes, you might consider running such a database publicly
260
+ accessible (Heroku actually does that for all of its Postgres databases unless they are within private spaces). Then we can connect to
261
+ such a database from everywhere with only the correct username/password.
262
+
263
+ By default, we have structured our templates to accomplish this with only a single free tier or low tier AWS RDS instance
264
+ that can serve all your development/testing needs for small/medium applications, e.g., as follows:
265
+
266
+ ```
267
+ aws-rds-single-pg-instance
268
+ mydb-staging
269
+ mydb-review-111
270
+ mydb-review-222
271
+ mydb-review-333
272
+ ```
273
+
274
+ Additionally, we provide a default `postgres` template in this repo optimized for Control Plane and suitable
275
+ for development purposes.
276
+
277
+ ## In-memory databases
278
+
279
+ E.g. Redis, Memcached.
280
+
281
+ For development purposes, it's useful to set those up as Control Plane workloads, as in most cases they don't keep any
282
+ valuable data and can be safely restarted (sometimes), which doesn't affect application performance.
283
+
284
+ For production purposes or where restarts are not an option, you should use external cloud services.
285
+
286
+ We provide default `redis` and `memcached` templates in this repo optimized for Control Plane and suitable
287
+ for development purposes.
288
+
289
+ ## CLI commands reference:
290
+
291
+ Click [here](/docs/commands.md) to see the commands.
292
+
293
+ You can also run:
294
+
295
+ ```sh
296
+ cpl --help
297
+ ```
298
+
299
+ ## Mapping of Heroku Commands to `cpl` and `cpln`
300
+
301
+ **`[WIP]`**
302
+
303
+ | Heroku Command | `cpl` or `cpln` |
304
+ | ---------------------------------------------------------------------------------------------------------------- | --------------- |
305
+ | `[heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type)` | `cpl ps` |
306
+ | `[heroku config](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-config)` | ? |
307
+ | `[heroku maintenance](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-maintenance)` | ? |
308
+ | `[heroku logs](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs)` | `cpl logs` |
309
+ | `[heroku pg](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pg-database)` | ? |
310
+ | `[heroku pipelines:promote](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pipelines-promote)` | `cpl promote` |
311
+ | `[heroku psql](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-psql-database)` | ? |
312
+ | `[heroku redis](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-redis-database)` | ? |
313
+ | `[heroku releases](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-releases)` | ? |
314
+
315
+ ## Examples
316
+
317
+ 1. See `examples/` and `templates/` folders of this repo.
318
+ 2. See `.controlplane` directory of this live example: [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ RuboCop::RakeTask.new
10
+
11
+ task default: %i[spec rubocop]
data/bin/cpl ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "cpl"
5
+
6
+ Cpl::Cli.start
data/cpl ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+
3
+ SCRIPT_DIR=$(dirname $(realpath $0))
4
+
5
+ # exports .env to vars
6
+ #
7
+ # Example .env:
8
+ # CPLN_TOKEN=xxx
9
+ #
10
+ if [ -f "$SCRIPT_DIR/.env" ]; then
11
+ export $(grep -v '^#' $SCRIPT_DIR/.env | xargs -0)
12
+ fi
13
+
14
+ # exec $SCRIPT_DIR/old_commands/main.sh "$@"
15
+ exec ruby $SCRIPT_DIR/lib/main.rb "$@"
data/cpl.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/cpl/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "cpl"
7
+ spec.version = Cpl::VERSION
8
+ spec.authors = ["Justin Gordon", "Sergey Tarasov"]
9
+ spec.email = ["justin@shakacode.com", "sergey@shakacode.com"]
10
+
11
+ spec.summary = "Heroku to Control Plane"
12
+ spec.description = "Helper CLI for migrating from Heroku to Control Plane"
13
+ spec.homepage = "https://github.com/shakacode/heroku-to-control-plane"
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = ">= 2.7.0"
17
+
18
+ spec.add_dependency "cgi", "~> 0.3.6"
19
+ spec.add_dependency "debug", "~> 1.7.1"
20
+ spec.add_dependency "dotenv", "~> 2.8.1"
21
+ spec.add_dependency "json", "~> 2.6.3"
22
+ spec.add_dependency "net-http", "~> 0.3.2"
23
+ spec.add_dependency "pathname", "~> 0.2.1"
24
+ spec.add_dependency "psych", "~> 5.1.0"
25
+ spec.add_dependency "tempfile", "~> 0.1.3"
26
+ spec.add_dependency "thor", "~> 1.2.1"
27
+ spec.add_dependency "yaml", "~> 0.2.1"
28
+
29
+ spec.add_development_dependency "rspec", "~> 3.12.0"
30
+ spec.add_development_dependency "rubocop", "~> 1.45.0"
31
+ spec.add_development_dependency "rubocop-rake", "~> 0.6.0"
32
+ spec.add_development_dependency "rubocop-rspec", "~> 2.18.1"
33
+ spec.add_development_dependency "simplecov", "~> 0.22.0"
34
+
35
+ spec.files = `git ls-files -z`.split("\x0").reject do |file|
36
+ file.match(%r{^(coverage|pkg|spec|tmp)/})
37
+ end
38
+
39
+ spec.executables = ["cpl"]
40
+
41
+ spec.metadata["rubygems_mfa_required"] = "true"
42
+ end