renuo-cli 4.16.0 → 4.17.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7d2be942a488e9f935ad409f20fa275aea27af14713c6b98b155718208fbbbe
4
- data.tar.gz: 8b854cf2514442624fe57d6f25e6540575140f14b2ece1ecda41ad2f5ef767cb
3
+ metadata.gz: 4bd8ae089520815a2934d6aa8bd1b7209af01e717c1e623c0a53bfb0cda0931e
4
+ data.tar.gz: 49c94fd014528566a51727e6f7938b56ff8a0ec37aa93c5a4292b3ba10a0abd2
5
5
  SHA512:
6
- metadata.gz: 2b3b6acf9f8c2899d818ab72a1429835fc3f94ad003d8d6974c2bbee8d39819aeec07e5c947dd814f0626d1151fc007dff8d78664b7f84bd63d3d1ef2c6b68cc
7
- data.tar.gz: 612d0f7b4f197079cbb8e48c0cf7262a9d07f175e03c2318a7cc7a803451bc0c39c812ecebf13cd07b0c666090c0c21b1eedfecba3105ba6758fc616436349de
6
+ metadata.gz: 6d960d53deb1dc144cfeaa77311732139c0e29f651567934a7fbd3ea9d3a812f8f6fa77f83d90338ccc4fe55bf3f7a528aaa1e2191dbb120f09db031a13c8582
7
+ data.tar.gz: e70f032d4d4c1b7323cd5fc177d93e6c9d37ff83b72a54e3ee5be368eb07e88132fd81e50233217ef862ce1b3d5df696bfb957390f664f40b530f4e0a13360b7
data/README.md CHANGED
@@ -32,7 +32,8 @@ To release a new version, update the version number in `version.rb`, and then ru
32
32
 
33
33
  ## Release
34
34
 
35
- * Bump the version number in `lib/renuo/cli/version.rb` and commit to `main`
35
+ * Bump the version number in `lib/renuo/cli/version.rb`, run `bundle install`
36
+ to update the `Gemfile.lock` and commit to `main`
36
37
 
37
38
  ### Automatic
38
39
 
@@ -83,6 +83,11 @@ class Renuo::Cli::Commands::CheckDeploioStatus
83
83
  when "available", "success"
84
84
  puts "#{type} succeeded"
85
85
  true
86
+ when "superseded"
87
+ puts "release was superseded"
88
+ true
89
+ when "paused"
90
+ abort "app is paused"
86
91
  when "error", "failed", "failure"
87
92
  puts fetch_build_logs
88
93
  abort "#{type} failed"
@@ -20,13 +20,14 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
20
20
  - Configure repository access by generating SSH keys and adding them to 1Password.
21
21
  - Create the application and database for each specified environment.
22
22
  DESC
23
- c.example "renuo create-deploio-app",
23
+ c.example "renuo create-deploio-app my-app git@github.com:renuo/my-app.git",
24
24
  "Prompts the user for the necessary information and generates the commands " \
25
25
  "to create the project, databases, and apps on Deploio."
26
- c.action { new.run }
26
+ c.action { |args| new.run(args) }
27
27
  end
28
28
 
29
- def run
29
+ def run(args)
30
+ @project_name, @git_url = args
30
31
  parse_arguments
31
32
  setup_commands
32
33
  setup_environments
@@ -59,12 +60,12 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
59
60
 
60
61
  def set_project_name
61
62
  loop do
62
- @project_name = ask("Enter the project name (e.g: my-app): ")
63
-
64
63
  break if @project_name&.length&.between?(3, 63) && @project_name.match?(/^[a-z0-9-]+$/)
65
64
 
66
65
  say ">> Project name must be between 3 and 63 characters and can only contain lowercase letters, " \
67
66
  "numbers, and hyphens. Please try again.".colorize(:red)
67
+
68
+ @project_name = ask("Enter the project name (e.g: my-app): ")
68
69
  end
69
70
 
70
71
  @project_display_name = @project_name
@@ -73,10 +74,11 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
73
74
 
74
75
  def set_git_url
75
76
  loop do
76
- @git_url = ask("Enter the git URL (e.g: git@github.com:my-org/my-app.git): ")
77
77
  break if @git_url.present? && git_url_valid?(@git_url)
78
78
 
79
79
  say ">> Git URL must be provided and valid. Please try again.".colorize(:red)
80
+
81
+ @git_url = ask("Enter the git URL: ") { |q| q.default = "git@github.com:renuo/#{@project_name}.git" }
80
82
  end
81
83
 
82
84
  return unless http_git_url?(@git_url)
@@ -87,27 +89,16 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
87
89
 
88
90
  def set_postgres_version
89
91
  loop do
90
- @postgres_version = ask("Enter Postgres version (e.g., 16) or leave empty to skip database creation: ")
92
+ @postgres_version = ask("Enter Postgres version (e.g., 17) or leave empty to skip database creation: ")
91
93
  break if @postgres_version.empty? || @postgres_version.match?(/^\d+$/)
92
94
 
93
95
  say ">> The postgres version is invalid. Only major versions are allowed. " \
94
- "For example, use 16 instead of 16.4. Please try again.".colorize(:red)
96
+ "For example, use 17 instead of 17.4. Please try again.".colorize(:red)
95
97
  end
96
98
  end
97
99
 
98
- def set_vault_name # rubocop:disable Metrics/MethodLength
99
- loop do
100
- @vault_name = ask("Enter the 1Password vault name (leave empty to skip): ")
101
- if @vault_name.empty?
102
- say "Skipping 1Password vault setup. Defaulting to Deploio."
103
- @vault_name = "Deploio"
104
- break
105
- elsif @vault_name.present?
106
- break
107
- else
108
- say ">> The vault name must be provided. Please try again.".colorize(:red)
109
- end
110
- end
100
+ def set_vault_name
101
+ @vault_name = ask("Enter the 1Password vault name: ") { |q| q.default = "Deploio" }
111
102
  end
112
103
 
113
104
  def setup_commands
@@ -141,12 +132,20 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
141
132
  end
142
133
 
143
134
  def say_database_creation(environment)
144
- say <<~OUTPUT
145
- nctl create postgres #{environment} \\
146
- --project=#{@project_name} \\
147
- --postgres-version=#{@postgres_version} \\
148
- --machine-type=nine-db-xs
149
- OUTPUT
135
+ if environment == "main"
136
+ say <<~OUTPUT
137
+ nctl create postgres #{environment} \\
138
+ --project=#{@project_name} \\
139
+ --postgres-version=#{@postgres_version} \\
140
+ --machine-type=nine-db-xs
141
+ OUTPUT
142
+ else
143
+ say <<~OUTPUT
144
+ nctl create postgresdatabase #{environment} \\
145
+ --project=#{@project_name} \\
146
+ --postgres-database-version=#{@postgres_version}
147
+ OUTPUT
148
+ end
150
149
  end
151
150
 
152
151
  def say_app_creation(environment)
@@ -156,8 +155,8 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
156
155
  --git-ssh-private-key-from-file=#{GITHUB_SSH_KEY_FILE_NAME} \\
157
156
  --git-url=#{@git_url} \\
158
157
  --git-revision="#{environment}" \\
159
- --basic-auth=false `# Disabling Deploio basic auth as Rails app handles authentication` \\
160
- --build-env=SECRET_KEY_BASE='rails secret' `# Do not forget to generate the secret key` \\
158
+ --basic-auth=#{environment == "develop"} \\
159
+ --build-env=SECRET_KEY_BASE="$(rails secret)" \\
161
160
  --language=ruby \\
162
161
  --size=mini
163
162
  OUTPUT
@@ -167,6 +166,7 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
167
166
  say <<~OUTPUT
168
167
  # Create SSH key item in 1Password directly
169
168
  op item create \\
169
+ --account renuo.1password.com \\
170
170
  --category ssh \\
171
171
  --ssh-generate-key #{SSH_ALGORITHM.downcase} \\
172
172
  --title "#{@project_name}-deploy-key" \\
@@ -175,8 +175,10 @@ class Renuo::Cli::Commands::CreateDeploioApp # rubocop:disable Metrics/ClassLeng
175
175
 
176
176
  # Extract keys to temp files for deploio usage
177
177
  op item get "#{@project_name}-deploy-key" --vault #{@vault_name} \\
178
+ --account renuo.1password.com \\
178
179
  --reveal --fields "public key" > #{file_name}.pub
179
180
  op item get "#{@project_name}-deploy-key" --vault #{@vault_name} --reveal \\
181
+ --account renuo.1password.com \\
180
182
  --fields "private key" --format json | jq -r '.ssh_formats.openssh.value' > #{file_name}
181
183
  OUTPUT
182
184
  end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class Renuo::Cli::Commands::CreateDeploioObjectStorage
6
+ include CommandHelper
7
+
8
+ command "create-deploio-object-storage" do |c|
9
+ c.syntax = "renuo create-deploio-object-storage"
10
+ c.summary = "Generates the script necessary to setup object storage on Deploio."
11
+ c.description = <<~DESCRIPTION
12
+ This creates commands for creating buckets and bucket users.
13
+ It also guides you to set up ActiveStorage correctly, by setting the required ENV variables and config/storage.yml setting.
14
+
15
+ You will be asked for:
16
+ - project name so that the script can respect our naming conventions
17
+
18
+ The generated commands do the following:
19
+ - create a bucket user for each environment (main, develop)
20
+ - create buckets for each user who owns it
21
+ - enable versioning for main buckets
22
+ DESCRIPTION
23
+ c.example "Setup Deploio object storage (you will be asked for details)", "renuo create-deploio-object-storage"
24
+ c.example "renuo create-deploio-object-storage",
25
+ "Prompts the user for the necessary information and generates the commands " \
26
+ "to setup object storage on Deploio."
27
+ c.action { new.run }
28
+ end
29
+
30
+ def initialize
31
+ @project_name = ask('Project name (eg: "renuo-mtextur"): ') { |q| q.validate = /.+/ }
32
+ @location = ask('Location (Default: "nine-es34"): ') { |q| q.default = "nine-es34" }
33
+ end
34
+
35
+ BRANCHES = %w[main develop].freeze
36
+
37
+ def run
38
+ BRANCHES.each do |branch|
39
+ print_setup_commands(branch)
40
+ end
41
+ print_active_storage_config
42
+ end
43
+
44
+ private
45
+
46
+ def project_name_without_organisation
47
+ @project_name_without_organisation ||= @project_name.split("-")[1..].join("-")
48
+ end
49
+
50
+ def print_setup_commands(branch)
51
+ say "\n# Commands to create #{branch} bucket user and bucket\n".bold
52
+ versioning_flag = branch == "main" ? " --versioning" : ""
53
+ bucket_name = "#{project_name_without_organisation}-#{branch}"
54
+ say "nctl create bucketuser #{branch} --project #{@project_name} --location #{@location}\n"
55
+ say "nctl create bucket #{bucket_name} --project #{@project_name} --location #{@location}" \
56
+ "#{versioning_flag} --permissions reader=#{branch} --permissions writer=#{branch}\n"
57
+ end
58
+
59
+ def print_active_storage_config
60
+ say "\n# ActiveStorage Configuration".bold
61
+ print_storage_yml_config
62
+ print_retrieve_credentials
63
+ print_env_variables_config
64
+ print_active_storage_service_config
65
+ end
66
+
67
+ def print_storage_yml_config
68
+ puts <<~OUTPUT
69
+ Add the following service configuration to your "config/storage.yml" file:
70
+
71
+ deploio:
72
+ service: S3
73
+ access_key_id: <%= ENV["DEPLOIO_ACCESS_KEY"] %>
74
+ secret_access_key: <%= ENV["DEPLOIO_SECRET_KEY"] %>
75
+ endpoint: <%= ENV["DEPLOIO_ENDPOINT"] %>
76
+ region: us-east-1 # running in Switzerland, operated by Nine.
77
+ bucket: <%= ENV["DEPLOIO_BUCKET"] %>
78
+
79
+ INFO: For S3, a region must be specified. Deploio uses the S3 default value of us-east-1,
80
+ even though the servers are in Switzerland, operated by Nine.
81
+ OUTPUT
82
+ end
83
+
84
+ def print_retrieve_credentials
85
+ say "\n# Retrieve credentials from the bucket user".bold
86
+ say "After running the bucket user creation commands above, retrieve your credentials:\n\n"
87
+
88
+ BRANCHES.each do |branch|
89
+ say <<~OUTPUT
90
+ ## #{branch} environment credentials:
91
+ nctl get bucketuser #{branch} --project #{@project_name} --print-credentials
92
+
93
+ OUTPUT
94
+ end
95
+ end
96
+
97
+ def print_env_variables_config
98
+ say "\n# Set environment variables on your Deploio application".bold
99
+ say "Replace the placeholders with the values retrieved above:\n"
100
+
101
+ BRANCHES.each do |branch|
102
+ bucket_name = "#{project_name_without_organisation}-#{branch}"
103
+ say <<~OUTPUT
104
+
105
+ # #{branch} environment:
106
+ nctl update app #{branch} \\
107
+ --project #{@project_name} \\
108
+ --env="DEPLOIO_ACCESS_KEY={ACCESS_KEY}" \\
109
+ --env="DEPLOIO_SECRET_KEY={SECRET_KEY}" \\
110
+ --env="DEPLOIO_ENDPOINT=https://#{@location}.objects.nineapis.ch" \\
111
+ --env="DEPLOIO_BUCKET=#{bucket_name}"
112
+ OUTPUT
113
+ end
114
+ end
115
+
116
+ def print_active_storage_service_config
117
+ say "\n# Configure ActiveStorage in your Rails application".bold
118
+ say <<~OUTPUT
119
+ Set the ActiveStorage service in your production environment ("config/environments/production.rb"):
120
+
121
+ config.active_storage.service = :deploio
122
+ OUTPUT
123
+ end
124
+ end
@@ -51,7 +51,8 @@ class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
51
51
  end
52
52
 
53
53
  item_id = extract_item_id(private_link)
54
- item_json = get_item(item_id)
54
+ account_id = extract_account_id(private_link)
55
+ item_json = get_item(item_id, account_id)
55
56
  return if item_json.nil?
56
57
 
57
58
  item[:env_variables]&.each do |env_variable|
@@ -67,8 +68,15 @@ class Renuo::Cli::Commands::FetchSecrets # rubocop:disable Metrics/ClassLength
67
68
  /&i=([^&]+)/.match(private_link)[1]
68
69
  end
69
70
 
70
- def get_item(item_id)
71
- output = execute_command(command: "op item get #{item_id} --format json",
71
+ def extract_account_id(private_link)
72
+ /&h=([^&]+)/.match(private_link)&.[](1)
73
+ end
74
+
75
+ def get_item(item_id, account_id = nil)
76
+ command = "op item get #{item_id} --format json"
77
+ command += " --account #{account_id}" if account_id
78
+
79
+ output = execute_command(command: command,
72
80
  success_message: "",
73
81
  error_message: "Error fetching item #{item_id}." \
74
82
  "Check `private_link` in your #{CONFIG_FILE} file.")
@@ -3,7 +3,7 @@
3
3
  # :nocov:
4
4
  module Renuo
5
5
  class Cli
6
- VERSION = "4.16.0"
6
+ VERSION = "4.17.2"
7
7
  NAME = "renuo-cli"
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renuo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.16.0
4
+ version: 4.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renuo AG
@@ -85,6 +85,7 @@ files:
85
85
  - lib/renuo/cli/commands/configure_sentry.rb
86
86
  - lib/renuo/cli/commands/create_aws_project.rb
87
87
  - lib/renuo/cli/commands/create_deploio_app.rb
88
+ - lib/renuo/cli/commands/create_deploio_object_storage.rb
88
89
  - lib/renuo/cli/commands/create_heroku_app.rb
89
90
  - lib/renuo/cli/commands/create_new_logins.rb
90
91
  - lib/renuo/cli/commands/create_pr.rb
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  - !ruby/object:Gem::Version
136
137
  version: '0'
137
138
  requirements: []
138
- rubygems_version: 3.7.2
139
+ rubygems_version: 4.0.2
139
140
  specification_version: 4
140
141
  summary: The Renuo CLI automates some common workflows.
141
142
  test_files: []