cpl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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