Skip to content

Commit

Permalink
feat: allow CPLN_ORG and CPLN_APP env vars per app
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelgomesxyz committed Nov 23, 2023
1 parent b67b630 commit c837226
Show file tree
Hide file tree
Showing 36 changed files with 256 additions and 156 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ apps:
my-app-production:
<<: *common

# You can also opt out of allowing the use of CPLN_ORG and CPLN_APP env vars per app.
# It's recommended to leave this off for production, to avoid any accidents.
allow_org_override_by_env: false
allow_app_override_by_env: false

# Use a different organization for production.
cpln_org: my-org-production

Expand Down
56 changes: 52 additions & 4 deletions examples/controlplane.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@ allow_app_override_by_env: true

aliases:
common: &common
# Organization name for staging (customize to your needs).
# Production apps will use a different organization, specified below, for security.
# Organization for staging and QA apps is typically set as an alias.
# Production apps will use a different organization, specified in `apps`, for security.
# Change this value to your organization name
# or set the CPLN_ORG env var and it will override this for all `cpl` commands
# (provided that `allow_org_override_by_env` is set to `true`).
cpln_org: my-org-staging

# Example apps use only one location. Control Plane offers the ability to use multiple locations.
# TODO: Allow specification of multiple locations.
default_location: aws-us-east-2

# Allows running the command `cpl setup-app`
# instead of `cpl apply-template gvc redis postgres memcached rails sidekiq`.
setup:
- gvc
- redis
- postgres
- memcached
- rails
- sidekiq

# Configure the workload name used as a template for one-off scripts, like a Heroku one-off dyno.
one_off_workload: rails

Expand All @@ -30,26 +42,62 @@ aliases:
- postgres
- memcached

# Configure the workload name used when maintenance mode is on (defaults to "maintenance")
# Configure the workload name used when maintenance mode is on (defaults to "maintenance").
maintenance_workload: maintenance

# Fixes the remote terminal size to match the local terminal size
# when running the commands `cpl run` or `cpl run:detached`.
fix_terminal_size: true

# Apps with a deployed image created before this amount of days will be listed for deletion
# when running the command `cpl cleanup-stale-apps`.
stale_app_image_deployed_days: 5

# Images that exceed this quantity will be listed for deletion
# when running the command `cpl cleanup-images`.
image_retention_max_qty: 20

# Images created before this amount of days will be listed for deletion
# when running the command `cpl cleanup-images` (`image_retention_max_qty` takes precedence).
image_retention_days: 5

# Run workloads created before this amount of days will be listed for deletion
# when running the command `cpl run:cleanup`.
stale_run_workload_created_days: 2

apps:
my-app-staging:
# Use the values from the common section above.
<<: *common

my-app-review:
<<: *common

# If `match_if_app_name_starts_with` is `true`, then use this config for app names starting with this name,
# e.g., "my-app-review-pr123", "my-app-review-anything-goes", etc.
match_if_app_name_starts_with: true

my-app-production:
<<: *common

# You can also opt out of allowing the use of CPLN_ORG and CPLN_APP env vars per app.
# It's recommended to leave this off for production, to avoid any accidents.
allow_org_override_by_env: false
allow_app_override_by_env: false

# Use a different organization for production.
cpln_org: my-org-production

# Allows running the command `cpl promote-app-from-upstream -a my-app-production`
# to promote the staging app to production.
upstream: my-app-staging

# Used by the command `cpl promote-app-from-upstream` to run a release script before deploying.
# This is relative to the `.controlplane/` directory.
release_script: release_script

my-app-other:
<<: *common

# You can specify a different `Dockerfile` relative to the `.controlplane/` directory (defaults to "Dockerfile").
dockerfile: ../some_other/Dockerfile
2 changes: 1 addition & 1 deletion lib/command/apply_template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def confirm_workload(template)
def apply_template(filename)
data = File.read(filename)
.gsub("APP_GVC", config.app)
.gsub("APP_LOCATION", config[:default_location])
.gsub("APP_LOCATION", config.current!(:default_location))
.gsub("APP_ORG", config.org)
.gsub("APP_IMAGE", latest_image)

Expand Down
2 changes: 1 addition & 1 deletion lib/command/build_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BuildImage < Base
def call # rubocop:disable Metrics/MethodLength
ensure_docker_running!

dockerfile = config.current[:dockerfile] || "Dockerfile"
dockerfile = config.current(:dockerfile) || "Dockerfile"
dockerfile = "#{config.app_cpln_dir}/#{dockerfile}"

raise "Can't find Dockerfile at '#{dockerfile}'." unless File.exist?(dockerfile)
Expand Down
4 changes: 2 additions & 2 deletions lib/command/cleanup_images.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def call # rubocop:disable Metrics/MethodLength
private

def ensure_max_qty_or_days!
@image_retention_max_qty = config.current[:image_retention_max_qty]
@image_retention_days = config.current[:image_retention_days]
@image_retention_max_qty = config.current(:image_retention_max_qty)
@image_retention_days = config.current(:image_retention_days)
return if @image_retention_max_qty || @image_retention_days

raise "Can't find either option 'image_retention_max_qty' or 'image_retention_days' " \
Expand Down
2 changes: 1 addition & 1 deletion lib/command/cleanup_stale_apps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def stale_apps # rubocop:disable Metrics/MethodLength
apps = []

now = DateTime.now
stale_app_image_deployed_days = config[:stale_app_image_deployed_days]
stale_app_image_deployed_days = config.current!(:stale_app_image_deployed_days)

gvcs = cp.gvc_query(config.app)["items"]
gvcs.each do |gvc|
Expand Down
5 changes: 0 additions & 5 deletions lib/command/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ class Config < Base
EX

def call # rubocop:disable Metrics/MethodLength
if config.org_comes_from_env
puts Shell.color("Org comes from CPLN_ORG env var", :red)
puts
end

if config.app
puts "#{Shell.color("Current config (app '#{config.app}')", :blue)}:"
puts pretty_print(config.current)
Expand Down
2 changes: 1 addition & 1 deletion lib/command/copy_image_from_upstream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CopyImageFromUpstream < Base
def call # rubocop:disable Metrics/MethodLength
ensure_docker_running!

@upstream = config[:upstream]
@upstream = config.current!(:upstream)
@upstream_org = config.apps[@upstream.to_sym][:cpln_org] || ENV.fetch("CPLN_ORG_UPSTREAM", nil)
ensure_upstream_org!

Expand Down
2 changes: 1 addition & 1 deletion lib/command/deploy_image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def call # rubocop:disable Metrics/MethodLength

image = latest_image

config[:app_workloads].each do |workload|
config.current!(:app_workloads).each do |workload|
workload_data = cp.fetch_workload!(workload)
workload_data.dig("spec", "containers").each do |container|
next unless container["image"].match?(%r{^/org/#{config.org}/image/#{config.app}:})
Expand Down
2 changes: 1 addition & 1 deletion lib/command/info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def call
@missing_apps_workloads = {}
@missing_apps_starting_with = {}

if config.app && !config.current[:match_if_app_name_starts_with]
if config.app && !config.current(:match_if_app_name_starts_with)
single_app_info
else
multiple_apps_info
Expand Down
2 changes: 1 addition & 1 deletion lib/command/logs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Logs < Base
EX

def call
workload = config.options[:workload] || config[:one_off_workload]
workload = config.options[:workload] || config.current!(:one_off_workload)
cp.logs(workload: workload)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/command/maintenance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class Maintenance < Base
WITH_INFO_HEADER = false

def call # rubocop:disable Metrics/MethodLength
one_off_workload = config[:one_off_workload]
maintenance_workload = config.current[:maintenance_workload] || "maintenance"
one_off_workload = config.current!(:one_off_workload)
maintenance_workload = config.current(:maintenance_workload) || "maintenance"

domain_data = cp.find_domain_for([one_off_workload, maintenance_workload])
unless domain_data
Expand Down
4 changes: 2 additions & 2 deletions lib/command/maintenance_off.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class MaintenanceOff < Base
DESC

def call # rubocop:disable Metrics/MethodLength
one_off_workload = config[:one_off_workload]
maintenance_workload = config.current[:maintenance_workload] || "maintenance"
one_off_workload = config.current!(:one_off_workload)
maintenance_workload = config.current(:maintenance_workload) || "maintenance"

domain_data = cp.find_domain_for([one_off_workload, maintenance_workload])
unless domain_data
Expand Down
4 changes: 2 additions & 2 deletions lib/command/maintenance_on.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class MaintenanceOn < Base
DESC

def call # rubocop:disable Metrics/MethodLength
one_off_workload = config[:one_off_workload]
maintenance_workload = config.current[:maintenance_workload] || "maintenance"
one_off_workload = config.current!(:one_off_workload)
maintenance_workload = config.current(:maintenance_workload) || "maintenance"

domain_data = cp.find_domain_for([one_off_workload, maintenance_workload])
unless domain_data
Expand Down
2 changes: 1 addition & 1 deletion lib/command/maintenance_set_page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class MaintenanceSetPage < Base
DESC

def call
maintenance_workload = config.current[:maintenance_workload] || "maintenance"
maintenance_workload = config.current(:maintenance_workload) || "maintenance"

maintenance_workload_data = cp.fetch_workload!(maintenance_workload)
maintenance_workload_data.dig("spec", "containers").each do |container|
Expand Down
2 changes: 1 addition & 1 deletion lib/command/open.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Open < Base
EX

def call
workload = config.options[:workload] || config[:one_off_workload]
workload = config.options[:workload] || config.current!(:one_off_workload)
data = cp.fetch_workload!(workload)
url = data["status"]["endpoint"]
opener = `which xdg-open open`.split("\n").grep_v("not found").first
Expand Down
2 changes: 1 addition & 1 deletion lib/command/promote_app_from_upstream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def call
private

def check_release_script
release_script_name = config.current[:release_script]
release_script_name = config.current(:release_script)
unless release_script_name
progress.puts("Can't find option 'release_script' for app '#{config.app}' in 'controlplane.yml'. " \
"Skipping release script.\n\n")
Expand Down
4 changes: 2 additions & 2 deletions lib/command/ps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ def call
cp.fetch_gvc!

workloads = [config.options[:workload]] if config.options[:workload]
workloads ||= config[:app_workloads] + config[:additional_workloads]
workloads ||= config.current!(:app_workloads) + config.current!(:additional_workloads)
workloads.each do |workload|
cp.fetch_workload!(workload)

result = cp.workload_get_replicas(workload, location: config[:default_location])
result = cp.workload_get_replicas(workload, location: config.current!(:default_location))
result["items"].each { |replica| puts replica }
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/command/ps_restart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PsRestart < Base

def call
workloads = [config.options[:workload]] if config.options[:workload]
workloads ||= config[:app_workloads] + config[:additional_workloads]
workloads ||= config.current!(:app_workloads) + config.current!(:additional_workloads)

workloads.each do |workload|
step("Restarting workload '#{workload}'") do
Expand Down
2 changes: 1 addition & 1 deletion lib/command/ps_start.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class PsStart < Base

def call
@workloads = [config.options[:workload]] if config.options[:workload]
@workloads ||= config[:app_workloads] + config[:additional_workloads]
@workloads ||= config.current!(:app_workloads) + config.current!(:additional_workloads)

@workloads.reverse_each do |workload|
step("Starting workload '#{workload}'") do
Expand Down
2 changes: 1 addition & 1 deletion lib/command/ps_stop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class PsStop < Base

def call
@workloads = [config.options[:workload]] if config.options[:workload]
@workloads ||= config[:app_workloads] + config[:additional_workloads]
@workloads ||= config.current!(:app_workloads) + config.current!(:additional_workloads)

@workloads.each do |workload|
step("Stopping workload '#{workload}'") do
Expand Down
2 changes: 1 addition & 1 deletion lib/command/ps_wait.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PsWait < Base

def call
@workloads = [config.options[:workload]] if config.options[:workload]
@workloads ||= config[:app_workloads] + config[:additional_workloads]
@workloads ||= config.current!(:app_workloads) + config.current!(:additional_workloads)

@workloads.reverse_each do |workload|
step("Waiting for workload '#{workload}' to be ready", retry_on_failure: true) do
Expand Down
6 changes: 3 additions & 3 deletions lib/command/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class Run < Base
attr_reader :location, :workload, :one_off, :container

def call # rubocop:disable Metrics/MethodLength
@location = config[:default_location]
@workload = config.options["workload"] || config[:one_off_workload]
@location = config.current!(:default_location)
@workload = config.options["workload"] || config.current!(:one_off_workload)
@one_off = "#{workload}-run-#{rand(1000..9999)}"

step("Cloning workload '#{workload}' on app '#{config.options[:app]}' to '#{one_off}'") do
Expand Down Expand Up @@ -124,7 +124,7 @@ def runner_script # rubocop:disable Metrics/MethodLength
end

# NOTE: fixes terminal size to match local terminal
if config.current[:fix_terminal_size] || config.options[:terminal_size]
if config.current(:fix_terminal_size) || config.options[:terminal_size]
if config.options[:terminal_size]
rows, cols = config.options[:terminal_size].split(",")
else
Expand Down
2 changes: 1 addition & 1 deletion lib/command/run_cleanup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def stale_run_workloads # rubocop:disable Metrics/MethodLength
run_workloads = []

now = DateTime.now
stale_run_workload_created_days = config[:stale_run_workload_created_days]
stale_run_workload_created_days = config.current!(:stale_run_workload_created_days)

interactive_workloads = cp.query_workloads("-run-", partial_workload_match: true)["items"]
non_interactive_workloads = cp.query_workloads("-runner-", partial_workload_match: true)["items"]
Expand Down
4 changes: 2 additions & 2 deletions lib/command/run_detached.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class RunDetached < Base # rubocop:disable Metrics/ClassLength
attr_reader :location, :workload, :one_off, :container

def call # rubocop:disable Metrics/MethodLength
@location = config[:default_location]
@workload = config.options["workload"] || config[:one_off_workload]
@location = config.current!(:default_location)
@workload = config.options["workload"] || config.current!(:one_off_workload)
@one_off = "#{workload}-runner-#{rand(1000..9999)}"

step("Cloning workload '#{workload}' on app '#{config.options[:app]}' to '#{one_off}'") do
Expand Down
2 changes: 1 addition & 1 deletion lib/command/setup_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SetupApp < Base
DESC

def call
templates = config[:setup]
templates = config.current!(:setup)

app = cp.fetch_gvc
if app
Expand Down
Loading

0 comments on commit c837226

Please sign in to comment.