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 +4 -4
- data/README.md +2 -1
- data/lib/renuo/cli/commands/check_deploio_status.rb +5 -0
- data/lib/renuo/cli/commands/create_deploio_app.rb +31 -29
- data/lib/renuo/cli/commands/create_deploio_object_storage.rb +124 -0
- data/lib/renuo/cli/commands/fetch_secrets.rb +11 -3
- data/lib/renuo/cli/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4bd8ae089520815a2934d6aa8bd1b7209af01e717c1e623c0a53bfb0cda0931e
|
|
4
|
+
data.tar.gz: 49c94fd014528566a51727e6f7938b56ff8a0ec37aa93c5a4292b3ba10a0abd2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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.,
|
|
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
|
|
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
|
|
99
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
160
|
-
--build-env=SECRET_KEY_BASE=
|
|
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
|
-
|
|
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
|
|
71
|
-
|
|
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.")
|
data/lib/renuo/cli/version.rb
CHANGED
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.
|
|
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:
|
|
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: []
|