cpl 1.1.2 → 1.2.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.
data/lib/cpl.rb CHANGED
@@ -141,11 +141,12 @@ module Cpl
141
141
  usage = command_class::USAGE.empty? ? name : command_class::USAGE
142
142
  requires_args = command_class::REQUIRES_ARGS
143
143
  default_args = command_class::DEFAULT_ARGS
144
- command_options = command_class::OPTIONS + [::Command::Base.verbose_option]
144
+ command_options = command_class::OPTIONS + ::Command::Base.common_options
145
145
  description = command_class::DESCRIPTION
146
146
  long_description = command_class::LONG_DESCRIPTION
147
147
  examples = command_class::EXAMPLES
148
148
  hide = command_class::HIDE || deprecated
149
+ with_info_header = command_class::WITH_INFO_HEADER
149
150
 
150
151
  long_description += "\n#{examples}" if examples.length.positive?
151
152
 
@@ -160,6 +161,10 @@ module Cpl
160
161
  method_option(option[:name], **option[:params])
161
162
  end
162
163
 
164
+ # We'll handle required options manually in `Config`
165
+ required_options = command_options.select { |option| option[:params][:required] }.map { |option| option[:name] }
166
+ disable_required_check! name_for_method.to_sym if required_options.any?
167
+
163
168
  define_method(name_for_method) do |*provided_args| # rubocop:disable Metrics/MethodLength
164
169
  if deprecated
165
170
  ::Shell.warn_deprecated("Command '#{command_key}' is deprecated, " \
@@ -176,7 +181,9 @@ module Cpl
176
181
  raise_args_error.call(args, nil) if (args.empty? && requires_args) || (!args.empty? && !requires_args)
177
182
 
178
183
  begin
179
- config = Config.new(args, options)
184
+ config = Config.new(args, options, required_options)
185
+
186
+ Cpl::Cli.show_info_header(config) if with_info_header
180
187
 
181
188
  command_class.new(config).call
182
189
  rescue RuntimeError => e
@@ -186,6 +193,25 @@ module Cpl
186
193
  rescue StandardError => e
187
194
  ::Shell.abort("Unable to load command: #{e.message}")
188
195
  end
196
+
197
+ def self.show_info_header(config) # rubocop:disable Metrics/MethodLength
198
+ return if @showed_info_header
199
+
200
+ rows = {}
201
+ rows["ORG"] = config.org || "NOT PROVIDED!"
202
+ rows["ORG"] += " (comes from CPLN_ORG env var)" if config.org_comes_from_env
203
+ rows["APP"] = config.app || "NOT PROVIDED!"
204
+ rows["APP"] += " (comes from CPLN_APP env var)" if config.app_comes_from_env
205
+
206
+ rows.each do |key, value|
207
+ puts "#{key}: #{value}"
208
+ end
209
+
210
+ @showed_info_header = true
211
+
212
+ # Add a newline after the info header
213
+ puts
214
+ end
189
215
  end
190
216
  end
191
217
 
@@ -0,0 +1,27 @@
1
+ FROM ruby:3.1.2
2
+
3
+ RUN apt-get update
4
+
5
+ WORKDIR /app
6
+
7
+ # install ruby gems
8
+ COPY Gemfile* ./
9
+
10
+ RUN bundle config set without 'development test' && \
11
+ bundle config set with 'staging production' && \
12
+ bundle install --jobs=3 --retry=3
13
+
14
+ COPY . ./
15
+
16
+ ENV RAILS_ENV=production
17
+
18
+ # compiling assets requires any value for ENV of SECRET_KEY_BASE
19
+ ENV SECRET_KEY_BASE=NOT_USED_NON_BLANK
20
+
21
+ RUN rails assets:precompile
22
+
23
+ # add entrypoint
24
+ COPY .controlplane/entrypoint.sh ./
25
+ ENTRYPOINT ["/app/entrypoint.sh"]
26
+
27
+ CMD ["rails", "s"]
@@ -0,0 +1,57 @@
1
+ # Keys beginning with "cpln_" correspond to your settings in Control Plane.
2
+
3
+ # You can opt out of allowing the use of CPLN_ORG and CPLN_APP env vars
4
+ # to avoid any accidents with the wrong org / app.
5
+ allow_org_override_by_env: true
6
+ allow_app_override_by_env: true
7
+
8
+ aliases:
9
+ common: &common
10
+ # Organization name for staging (customize to your needs).
11
+ # Production apps will use a different organization, specified below, for security.
12
+ cpln_org: my-org-staging
13
+
14
+ # Example apps use only one location. Control Plane offers the ability to use multiple locations.
15
+ # TODO: Allow specification of multiple locations.
16
+ default_location: aws-us-east-2
17
+
18
+ # Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
19
+ one_off_workload: rails
20
+
21
+ # Workloads that are for the application itself and are using application Docker images.
22
+ app_workloads:
23
+ - rails
24
+
25
+ # Additional "service type" workloads, using non-application Docker images.
26
+ additional_workloads:
27
+ - postgres
28
+
29
+ # Configure the workload name used when maintenance mode is on (defaults to "maintenance")
30
+ maintenance_workload: maintenance
31
+
32
+ apps:
33
+ my-app-staging:
34
+ # Use the values from the common section above.
35
+ <<: *common
36
+ my-app-review:
37
+ <<: *common
38
+ # If `match_if_app_name_starts_with` is `true`, then use this config for app names starting with this name,
39
+ # e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
40
+ match_if_app_name_starts_with: true
41
+ my-app-production:
42
+ <<: *common
43
+
44
+ # You can also opt out of allowing the use of CPLN_ORG and CPLN_APP env vars per app.
45
+ # It's recommended to leave this off for production, to avoid any accidents.
46
+ allow_org_override_by_env: false
47
+ allow_app_override_by_env: false
48
+
49
+ # Use a different organization for production.
50
+ cpln_org: my-org-production
51
+ # Allows running the command `cpl promote-app-from-upstream -a my-app-production`
52
+ # to promote the staging app to production.
53
+ upstream: my-app-staging
54
+ my-app-other:
55
+ <<: *common
56
+ # You can specify a different `Dockerfile` relative to the `.controlplane/` directory (defaults to "Dockerfile").
57
+ dockerfile: ../some_other/Dockerfile
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+ # Runs before the main command
3
+
4
+ echo " -- Preparing database"
5
+ rails db:prepare
6
+
7
+ echo " -- Finishing entrypoint.sh, executing '$@'"
8
+ exec "$@"
@@ -0,0 +1,21 @@
1
+ # Template setup of the GVC, roughly corresponding to a Heroku app
2
+ kind: gvc
3
+ name: APP_GVC
4
+ spec:
5
+ # For using templates for test apps, put ENV values here, stored in git repo.
6
+ # Production apps will have values configured manually after app creation.
7
+ env:
8
+ - name: DATABASE_URL
9
+ # Password does not matter because host postgres.APP_GVC.cpln.local can only be accessed
10
+ # locally within CPLN GVC, and postgres running on a CPLN workload is something only for a
11
+ # test app that lacks persistence.
12
+ value: 'postgres://the_user:the_password@postgres.APP_GVC.cpln.local:5432/APP_GVC'
13
+ - name: RAILS_ENV
14
+ value: production
15
+ - name: RAILS_SERVE_STATIC_FILES
16
+ value: 'true'
17
+
18
+ # Part of standard configuration
19
+ staticPlacement:
20
+ locationLinks:
21
+ - /org/APP_ORG/location/APP_LOCATION
@@ -0,0 +1,176 @@
1
+ # Comes from example at
2
+ # https://github.com/controlplane-com/examples/blob/main/examples/postgres/manifest.yaml
3
+
4
+ kind: volumeset
5
+ name: postgres-poc-vs
6
+ description: postgres-poc-vs
7
+ spec:
8
+ autoscaling:
9
+ maxCapacity: 1000
10
+ minFreePercentage: 1
11
+ scalingFactor: 1.1
12
+ fileSystemType: ext4
13
+ initialCapacity: 10
14
+ performanceClass: general-purpose-ssd
15
+ snapshots:
16
+ createFinalSnapshot: true
17
+ retentionDuration: 7d
18
+
19
+ ---
20
+ kind: secret
21
+ name: postgres-poc-credentials
22
+ description: ''
23
+ type: dictionary
24
+ data:
25
+ password: the_password #Replace this with a real password
26
+ username: the_user #Replace this with a real username
27
+
28
+ ---
29
+ kind: secret
30
+ name: postgres-poc-entrypoint-script
31
+ type: opaque
32
+ data:
33
+ encoding: base64
34
+ payload: >-
35
+ IyEvdXNyL2Jpbi9lbnYgYmFzaAoKc291cmNlIC91c3IvbG9jYWwvYmluL2RvY2tlci1lbnRyeXBvaW50LnNoCgppbnN0YWxsX2RlcHMoKSB7CiAgYXB0LWdldCB1cGRhdGUgLXkgPiAvZGV2L251bGwKICBhcHQtZ2V0IGluc3RhbGwgY3VybCAteSA+IC9kZXYvbnVsbAogIGFwdC1nZXQgaW5zdGFsbCB1bnppcCAteSA+IC9kZXYvbnVsbAogIGN1cmwgImh0dHBzOi8vYXdzY2xpLmFtYXpvbmF3cy5jb20vYXdzY2xpLWV4ZS1saW51eC14ODZfNjQuemlwIiAtbyAiYXdzY2xpdjIuemlwIiA+IC9kZXYvbnVsbAogIHVuemlwIGF3c2NsaXYyLnppcCA+IC9kZXYvbnVsbAogIC4vYXdzL2luc3RhbGwgPiAvZGV2L251bGwKfQoKZGJfaGFzX2JlZW5fcmVzdG9yZWQoKSB7CiAgaWYgWyAhIC1mICIkUEdEQVRBL0NQTE5fUkVTVE9SRUQiIF07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKCiAgaWYgISBncmVwIC1xICJcLT4gJDEkIiAiJFBHREFUQS9DUExOX1JFU1RPUkVEIjsgdGhlbgogICAgcmV0dXJuIDEKICBlbHNlCiAgICByZXR1cm4gMAogIGZpCn0KCnJlc3RvcmVfZGIoKSB7Cgl3aGlsZSBbICEgLVMgL3Zhci9ydW4vcG9zdGdyZXNxbC8ucy5QR1NRTC41NDMyIF0KCWRvCiAgICBlY2hvICJXYWl0aW5nIDVzIGZvciBkYiBzb2NrZXQgdG8gYmUgYXZhaWxhYmxlIgogICAgc2xlZXAgNXMKICBkb25lCgoKCWlmICEgZGJfaGFzX2JlZW5fcmVzdG9yZWQgIiQxIjsgdGhlbgoJICBlY2hvICJJdCBhcHBlYXJzIGRiICckMScgaGFzIG5vdCB5ZXQgYmVlbiByZXN0b3JlZCBmcm9tIFMzLiBBdHRlbXB0aW5nIHRvIHJlc3RvcmUgJDEgZnJvbSAkMiIKCSAgaW5zdGFsbF9kZXBzCgkgIGRvY2tlcl9zZXR1cF9kYiAjRW5zdXJlcyAkUE9TVEdSRVNfREIgZXhpc3RzIChkZWZpbmVkIGluIHRoZSBlbnRyeXBvaW50IHNjcmlwdCBmcm9tIHRoZSBwb3N0Z3JlcyBkb2NrZXIgaW1hZ2UpCgkgIGF3cyBzMyBjcCAiJDIiIC0gfCBwZ19yZXN0b3JlIC0tY2xlYW4gLS1uby1hY2wgLS1uby1vd25lciAtZCAiJDEiIC1VICIkUE9TVEdSRVNfVVNFUiIKCSAgZWNobyAiJChkYXRlKTogJDIgLT4gJDEiIHwgY2F0ID4+ICIkUEdEQVRBL0NQTE5fUkVTVE9SRUQiCgllbHNlCgkgIGVjaG8gIkRiICckMScgYWxyZWFkeSBleGlzdHMuIFJlYWR5ISIKICBmaQp9CgpfbWFpbiAiJEAiICYKYmFja2dyb3VuZFByb2Nlc3M9JCEKCmlmIFsgLW4gIiRQT1NUR1JFU19BUkNISVZFX1VSSSIgXTsgdGhlbgogIHJlc3RvcmVfZGIgIiRQT1NUR1JFU19EQiIgIiRQT1NUR1JFU19BUkNISVZFX1VSSSIKZWxzZQogIGVjaG8gIkRlY2xpbmluZyB0byByZXN0b3JlIHRoZSBkYiBiZWNhdXNlIG5vIGFyY2hpdmUgdXJpIHdhcyBwcm92aWRlZCIKZmkKCndhaXQgJGJhY2tncm91bmRQcm9jZXNzCgoK
36
+
37
+ #Here is the ASCII-encoded version of the script in the secret above
38
+ #!/usr/bin/env bash
39
+ #
40
+ #source /usr/local/bin/docker-entrypoint.sh
41
+ #
42
+ #install_deps() {
43
+ # apt-get update -y > /dev/null
44
+ # apt-get install curl -y > /dev/null
45
+ # apt-get install unzip -y > /dev/null
46
+ # curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" > /dev/null
47
+ # unzip awscliv2.zip > /dev/null
48
+ # ./aws/install > /dev/null
49
+ #}
50
+ #
51
+ #db_has_been_restored() {
52
+ # if [ ! -f "$PGDATA/CPLN_RESTORED" ]; then
53
+ # return 1
54
+ # fi
55
+ #
56
+ # if ! grep -q "\-> $1$" "$PGDATA/CPLN_RESTORED"; then
57
+ # return 1
58
+ # else
59
+ # return 0
60
+ # fi
61
+ #}
62
+ #
63
+ #restore_db() {
64
+ # while [ ! -S /var/run/postgresql/.s.PGSQL.5432 ]
65
+ # do
66
+ # echo "Waiting 5s for db socket to be available"
67
+ # sleep 5s
68
+ # done
69
+ #
70
+ #
71
+ # if ! db_has_been_restored "$1"; then
72
+ # echo "It appears db '$1' has not yet been restored from S3. Attempting to restore $1 from $2"
73
+ # install_deps
74
+ # docker_setup_db #Ensures $POSTGRES_DB exists (defined in the entrypoint script from the postgres docker image)
75
+ # aws s3 cp "$2" - | pg_restore --clean --no-acl --no-owner -d "$1" -U "$POSTGRES_USER"
76
+ # echo "$(date): $2 -> $1" | cat >> "$PGDATA/CPLN_RESTORED"
77
+ # else
78
+ # echo "Db '$1' already exists. Ready!"
79
+ # fi
80
+ #}
81
+ #
82
+ #_main "$@" &
83
+ #backgroundProcess=$!
84
+ #
85
+ #if [ -n "$POSTGRES_ARCHIVE_URI" ]; then
86
+ # restore_db "$POSTGRES_DB" "$POSTGRES_ARCHIVE_URI"
87
+ #else
88
+ # echo "Declining to restore the db because no archive uri was provided"
89
+ #fi
90
+ #
91
+ #wait $backgroundProcess
92
+
93
+ ---
94
+ kind: identity
95
+ name: postgres-poc-identity
96
+ description: postgres-poc-identity
97
+
98
+ ---
99
+ kind: policy
100
+ name: postgres-poc-access
101
+ description: postgres-poc-access
102
+ bindings:
103
+ - permissions:
104
+ - reveal
105
+ # Uncomment these two
106
+ # - use
107
+ # - view
108
+ principalLinks:
109
+ - //gvc/APP_GVC/identity/postgres-poc-identity
110
+ targetKind: secret
111
+ targetLinks:
112
+ - //secret/postgres-poc-credentials
113
+ - //secret/postgres-poc-entrypoint-script
114
+
115
+ ---
116
+ kind: workload
117
+ name: postgres
118
+ description: postgres
119
+ spec:
120
+ type: stateful
121
+ containers:
122
+ - cpu: 1000m
123
+ memory: 512Mi
124
+ env:
125
+ # Uncomment next two envs will cause the db to be restored from the archive uri
126
+ # - name: POSTGRES_ARCHIVE_URI #Use this var to control the automatic restore behavior. If you leave it out, the db will start empty.
127
+ # value: s3://YOUR_BUCKET/PATH_TO_ARCHIVE_FILE
128
+ # - name: POSTGRES_DB #The name of the initial db in case of doing a restore
129
+ # value: test
130
+ - name: PGDATA #The location postgres stores the db. This can be anything other than /var/lib/postgresql/data, but it must be inside the mount point for the volume set
131
+ value: "/var/lib/postgresql/data/pg_data"
132
+ - name: POSTGRES_PASSWORD #The password for the default user
133
+ value: cpln://secret/postgres-poc-credentials.password
134
+ - name: POSTGRES_USER #The name of the default user
135
+ value: cpln://secret/postgres-poc-credentials.username
136
+ name: stateful
137
+ image: postgres:15
138
+ command: /bin/bash
139
+ args:
140
+ - "-c"
141
+ - "cat /usr/local/bin/cpln-entrypoint.sh >> ./cpln-entrypoint.sh && chmod u+x ./cpln-entrypoint.sh && ./cpln-entrypoint.sh postgres"
142
+ #command: "cpln-entrypoint.sh"
143
+ #args:
144
+ # - "postgres"
145
+ ports:
146
+ - number: 5432
147
+ protocol: tcp
148
+ volumes:
149
+ - uri: cpln://volumeset/postgres-poc-vs
150
+ path: "/var/lib/postgresql/data"
151
+ # Make the ENV value for the entry script a file
152
+ - uri: cpln://secret/postgres-poc-entrypoint-script
153
+ path: "/usr/local/bin/cpln-entrypoint.sh"
154
+ inheritEnv: false
155
+ livenessProbe:
156
+ tcpSocket:
157
+ port: 5432
158
+ failureThreshold: 1
159
+ readinessProbe:
160
+ tcpSocket:
161
+ port: 5432
162
+ failureThreshold: 1
163
+ identityLink: //identity/postgres-poc-identity
164
+ defaultOptions:
165
+ capacityAI: false
166
+ autoscaling:
167
+ metric: cpu
168
+ target: 95
169
+ maxScale: 1
170
+ firewallConfig:
171
+ external:
172
+ inboundAllowCIDR: []
173
+ outboundAllowCIDR:
174
+ - 0.0.0.0/0
175
+ internal:
176
+ inboundAllowType: same-gvc
@@ -0,0 +1,36 @@
1
+ # Template setup of Rails server workload, roughly corresponding to Heroku dyno
2
+ # type within Procfile.
3
+ kind: workload
4
+ name: rails
5
+ spec:
6
+ type: standard
7
+ containers:
8
+ - name: rails
9
+ # 300m is a good starting place for a test app. You can experiment with CPU configuration
10
+ # once your app is running.
11
+ cpu: 300m
12
+ env:
13
+ - name: LOG_LEVEL
14
+ value: debug
15
+ # Inherit other ENV values from GVC
16
+ inheritEnv: true
17
+ image: '/org/APP_ORG/image/APP_IMAGE'
18
+ # 512 corresponds to a standard 1x dyno type
19
+ memory: 512Mi
20
+ ports:
21
+ - number: 3000
22
+ protocol: http
23
+ defaultOptions:
24
+ # Start out like this for "test apps"
25
+ autoscaling:
26
+ # Max of 1 effectively disables autoscaling, so a like a Heroku dyno count of 1
27
+ maxScale: 1
28
+ capacityAI: false
29
+ firewallConfig:
30
+ external:
31
+ # Default to allow public access to Rails server
32
+ inboundAllowCIDR:
33
+ - 0.0.0.0/0
34
+ # Could configure outbound for more security
35
+ outboundAllowCIDR:
36
+ - 0.0.0.0/0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-10-25 00:00:00.000000000 Z
12
+ date: 2024-01-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: debug
@@ -242,6 +242,7 @@ files:
242
242
  - lib/command/deploy_image.rb
243
243
  - lib/command/env.rb
244
244
  - lib/command/exists.rb
245
+ - lib/command/generate.rb
245
246
  - lib/command/info.rb
246
247
  - lib/command/latest_image.rb
247
248
  - lib/command/logs.rb
@@ -269,11 +270,18 @@ files:
269
270
  - lib/core/controlplane_api.rb
270
271
  - lib/core/controlplane_api_cli.rb
271
272
  - lib/core/controlplane_api_direct.rb
273
+ - lib/core/helpers.rb
272
274
  - lib/core/scripts.rb
273
275
  - lib/core/shell.rb
274
276
  - lib/cpl.rb
275
277
  - lib/cpl/version.rb
276
278
  - lib/deprecated_commands.json
279
+ - lib/generator_templates/Dockerfile
280
+ - lib/generator_templates/controlplane.yml
281
+ - lib/generator_templates/entrypoint.sh
282
+ - lib/generator_templates/templates/gvc.yml
283
+ - lib/generator_templates/templates/postgres.yml
284
+ - lib/generator_templates/templates/rails.yml
277
285
  - rakelib/create_release.rake
278
286
  - script/add_command
279
287
  - script/check_command_docs
@@ -308,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
308
316
  - !ruby/object:Gem::Version
309
317
  version: '0'
310
318
  requirements: []
311
- rubygems_version: 3.4.12
319
+ rubygems_version: 3.4.21
312
320
  signing_key:
313
321
  specification_version: 4
314
322
  summary: Heroku to Control Plane