renuo-cli 4.23.0 → 4.24.1
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/lib/renuo/cli/commands/ci/check_deploio_status.rb +47 -28
- data/lib/renuo/cli/commands/create_aws_project.rb +2 -2
- data/lib/renuo/cli/commands/create_deploio_object_storage.rb +1 -1
- data/lib/renuo/cli/commands/setup_uptimerobot.rb +36 -52
- data/lib/renuo/cli/version.rb +3 -3
- data/lib/renuo/cli.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 456b03fb5a2d4bfa991efb571755004c00a515b672de04d5d99cb40176445201
|
|
4
|
+
data.tar.gz: 108335dbceb383a2be328ed1f16f28c97f0e62dcb5c270495704c30ed1ecd23f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d69d47ce40a20dd5b590d684e62117613c074db0f6178a0a8c4470af451ddb171637b6fe23e23198f4f5ed2fa40661cbbfb87ed5b92357adbbfb56085a0e2689
|
|
7
|
+
data.tar.gz: 81e5ff22b46aa16b11ad3fa9cf1a0a91d7eb0c91cebc88604611610018ea47957b5e51d0c44217e0c9cca75aa86dc7eca37aea5a9ce7600b211d1b9f6c3c69c3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# :
|
|
3
|
+
# simplecov:disable
|
|
4
4
|
module Renuo::Cli::Commands::Ci
|
|
5
5
|
class CheckDeploioStatus # rubocop:disable Metrics/ClassLength
|
|
6
6
|
TIMEOUT_IN_SECONDS = 600
|
|
@@ -17,13 +17,12 @@ module Renuo::Cli::Commands::Ci
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def run
|
|
20
|
-
puts "(1/2) Checking build status for revision #{@revision}..."
|
|
21
|
-
|
|
22
|
-
abort "build check timed out after #{TIMEOUT_IN_SECONDS} seconds"
|
|
20
|
+
puts "[RENUO-CLI] (1/2) Checking build status for revision #{@revision}..."
|
|
21
|
+
succeeded = with_streamed_build_logs { poll_build }
|
|
22
|
+
abort "[RENUO-CLI] build check timed out after #{TIMEOUT_IN_SECONDS} seconds" unless succeeded
|
|
23
23
|
|
|
24
|
-
puts "(2/2) Checking release status for build #{build_name}..."
|
|
25
|
-
|
|
26
|
-
abort "release check timed out after #{TIMEOUT_IN_SECONDS} seconds" if release.nil?
|
|
24
|
+
puts "[RENUO-CLI] (2/2) Checking release status for build #{build_name}..."
|
|
25
|
+
abort "[RENUO-CLI] release check timed out after #{TIMEOUT_IN_SECONDS} seconds" unless poll_release
|
|
27
26
|
end
|
|
28
27
|
|
|
29
28
|
private
|
|
@@ -33,9 +32,9 @@ module Renuo::Cli::Commands::Ci
|
|
|
33
32
|
@project = options.project
|
|
34
33
|
@revision = options.git_revision || ENV.fetch("SEMAPHORE_GIT_SHA", nil)
|
|
35
34
|
|
|
36
|
-
abort "missing app name" unless @app
|
|
37
|
-
abort "missing project name" unless @project
|
|
38
|
-
abort "this command must be run in Semaphore" unless @revision
|
|
35
|
+
abort "[RENUO-CLI] missing app name" unless @app
|
|
36
|
+
abort "[RENUO-CLI] missing project name" unless @project
|
|
37
|
+
abort "[RENUO-CLI] this command must be run in Semaphore" unless @revision
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
def system!(cmd)
|
|
@@ -46,13 +45,13 @@ module Renuo::Cli::Commands::Ci
|
|
|
46
45
|
command = "nctl get #{type} -a #{@app} -p #{@project} -o yaml"
|
|
47
46
|
stdout, stderr, status = Open3.capture3 command
|
|
48
47
|
|
|
49
|
-
abort "error fetching #{type} information: #{stderr}" unless status.success?
|
|
48
|
+
abort "[RENUO-CLI] error fetching #{type} information: #{stderr}" unless status.success?
|
|
50
49
|
Psych.load_stream stdout
|
|
51
50
|
end
|
|
52
51
|
|
|
53
|
-
def
|
|
52
|
+
def with_streamed_build_logs
|
|
54
53
|
pid = Process.spawn(
|
|
55
|
-
"nctl logs application #{@app} -p #{@project} --type
|
|
54
|
+
"nctl logs application #{@app} -p #{@project} --type=build -f --lines=100 --since 15m --no-labels",
|
|
56
55
|
out: $stdout, err: $stdout
|
|
57
56
|
)
|
|
58
57
|
yield
|
|
@@ -77,7 +76,7 @@ module Renuo::Cli::Commands::Ci
|
|
|
77
76
|
end
|
|
78
77
|
|
|
79
78
|
def build_name
|
|
80
|
-
|
|
79
|
+
build.dig("metadata", "name")
|
|
81
80
|
end
|
|
82
81
|
|
|
83
82
|
def build_status
|
|
@@ -90,44 +89,64 @@ module Renuo::Cli::Commands::Ci
|
|
|
90
89
|
end
|
|
91
90
|
end
|
|
92
91
|
|
|
92
|
+
def release_name
|
|
93
|
+
release.dig("metadata", "name")
|
|
94
|
+
end
|
|
95
|
+
|
|
93
96
|
def release_status
|
|
94
97
|
release.dig("status", "atProvider", "releaseStatus")
|
|
95
98
|
end
|
|
96
99
|
|
|
97
|
-
def succeeded?(
|
|
100
|
+
def succeeded?(type, name, status) # rubocop:disable Metrics/MethodLength
|
|
98
101
|
time = Time.current.iso8601.to_s
|
|
99
102
|
|
|
100
103
|
case status
|
|
101
104
|
when "available", "success"
|
|
102
|
-
puts "#{time} #{type} succeeded"
|
|
105
|
+
puts "[RENUO-CLI] #{time} #{type} #{name} succeeded"
|
|
103
106
|
true
|
|
104
107
|
when "superseded"
|
|
105
|
-
puts "#{time}
|
|
108
|
+
puts "[RENUO-CLI] #{time} #{type} #{name} was superseded"
|
|
106
109
|
true
|
|
107
110
|
when "paused"
|
|
108
|
-
abort "#{time} app is paused"
|
|
111
|
+
abort "[RENUO-CLI] #{time} app is paused"
|
|
109
112
|
when "error", "failed", "failure"
|
|
110
|
-
abort "#{time} #{type} failed"
|
|
113
|
+
abort "[RENUO-CLI] #{time} #{type} #{name} failed"
|
|
111
114
|
else
|
|
112
|
-
puts "#{time} #{type} status is #{status}, waiting..."
|
|
113
|
-
|
|
115
|
+
puts "[RENUO-CLI] #{time} #{type} #{name} status is #{status}, waiting..."
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def poll_build
|
|
121
|
+
poll do
|
|
122
|
+
next puts("[RENUO-CLI] no matching build found, waiting...") unless build
|
|
123
|
+
next true if succeeded?("build", build_name, build_status)
|
|
124
|
+
|
|
125
|
+
@build = nil
|
|
114
126
|
end
|
|
115
127
|
end
|
|
116
128
|
|
|
117
|
-
def
|
|
129
|
+
def poll_release
|
|
130
|
+
poll do
|
|
131
|
+
next puts("[RENUO-CLI] no matching release found, waiting...") unless release
|
|
132
|
+
next true if succeeded?("release", release_name, release_status)
|
|
133
|
+
|
|
134
|
+
@release = nil
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def poll
|
|
118
139
|
elapsed = 0
|
|
119
140
|
|
|
120
141
|
while elapsed < TIMEOUT_IN_SECONDS
|
|
121
|
-
if
|
|
122
|
-
break if succeeded?(send(:"#{type}_status"), type)
|
|
123
|
-
else
|
|
124
|
-
puts "no matching #{type} found, waiting..."
|
|
125
|
-
end
|
|
142
|
+
return true if yield
|
|
126
143
|
|
|
127
144
|
sleep INTERVAL_IN_SECONDS
|
|
128
145
|
elapsed += INTERVAL_IN_SECONDS
|
|
129
146
|
end
|
|
147
|
+
|
|
148
|
+
false
|
|
130
149
|
end
|
|
131
150
|
end
|
|
132
151
|
end
|
|
133
|
-
# :
|
|
152
|
+
# simplecov:enable
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# :
|
|
3
|
+
# simplecov:disable
|
|
4
4
|
class Renuo::Cli::Commands::CreateAwsProject
|
|
5
5
|
command "create-aws-project" do |c|
|
|
6
6
|
c.syntax = "renuo create-aws-project"
|
|
@@ -139,4 +139,4 @@ class Renuo::Cli::Commands::CreateAwsProject
|
|
|
139
139
|
CLOUDFRONT_COMMANDS
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
|
-
# :
|
|
142
|
+
# simplecov:enable
|
|
@@ -18,18 +18,24 @@ class Renuo::Cli::Commands::SetupUptimerobot
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def run
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
monitor = api_call(Net::HTTP::Post, "/monitors", create_monitor_params)
|
|
22
|
+
api_call(Net::HTTP::Post, "/monitors/#{monitor["id"]}/pause")
|
|
23
|
+
say "Successfully configured uptimerobot 🤩😎👍"
|
|
24
|
+
say "The monitor https://dashboard.uptimerobot.com/monitors/#{monitor["id"]} checks from Europe " \
|
|
25
|
+
"and is paused for now..."
|
|
26
|
+
say "You can start it once your app is ready to go live 🤠"
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
private
|
|
28
30
|
|
|
29
|
-
LIST_API_KEY_CMD = "op item list --tags renuo-cli-uptimerobot-api-key --format=json"
|
|
30
|
-
EXTRACT_API_KEY_CMD = "op item get --reveal --field credential"
|
|
31
31
|
def read_api_key
|
|
32
32
|
say "This command will configure uptimerobot for your project."
|
|
33
|
+
ENV.fetch("UPTIMEROBOT_API_KEY") { read_api_key_from_1password }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
LIST_API_KEY_CMD = "op item list --tags renuo-cli-uptimerobot-api-key --format=json"
|
|
37
|
+
EXTRACT_API_KEY_CMD = "op item get --reveal --field credential"
|
|
38
|
+
def read_api_key_from_1password
|
|
33
39
|
say "Fetching the uptimerobot api_key from 1Password..."
|
|
34
40
|
stdout, stderr, status = Open3.capture3("#{LIST_API_KEY_CMD} | #{EXTRACT_API_KEY_CMD}")
|
|
35
41
|
abort("Failed to fetch the uptimerobot api_key from 1Password: #{stderr.strip}") unless status.success?
|
|
@@ -46,60 +52,38 @@ class Renuo::Cli::Commands::SetupUptimerobot
|
|
|
46
52
|
URI.parse(args.first)
|
|
47
53
|
end
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
# Format is "id_threshold_recurrence": notify #uptime after 10 minutes of downtime, without re-notifying.
|
|
53
|
-
ALERT_CONTACTS = "7783511_10_0"
|
|
54
|
-
def create_robot_params
|
|
55
|
+
UPTIME_SLACK_CHANNEL_ALERT_CONTACT_ID = "7783511"
|
|
56
|
+
EUROPE_REGION = "eu"
|
|
57
|
+
def create_monitor_params
|
|
55
58
|
{
|
|
56
|
-
|
|
59
|
+
friendlyName: @url.host.downcase,
|
|
57
60
|
url: @url.to_s,
|
|
58
|
-
type:
|
|
61
|
+
type: "HTTP",
|
|
59
62
|
interval: 300,
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
timeout: 30,
|
|
64
|
+
checkSSLErrors: true,
|
|
65
|
+
# notify #uptime after 10 minutes of downtime, without re-notifying
|
|
66
|
+
assignedAlertContacts: [{ alertContactId: UPTIME_SLACK_CHANNEL_ALERT_CONTACT_ID, threshold: 10, recurrence: 0 }],
|
|
67
|
+
regionData: { REGION: [EUROPE_REGION], MANUAL_SELECTED: true },
|
|
68
|
+
domainExpirationReminder: false
|
|
62
69
|
}
|
|
63
70
|
end
|
|
64
71
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
say "The status for the monitored project has paused for now..."
|
|
73
|
-
say "You can start it once your app is ready to go live 🤠"
|
|
74
|
-
else
|
|
75
|
-
say "Something went wrong during the configuration...😕. Uptimerobot returned '#{response["error"]["message"]}'"
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def validate_new_project(robot_obj)
|
|
80
|
-
return if robot_obj["stat"] == "ok"
|
|
81
|
-
|
|
82
|
-
abort("An error occoured. Uptimerobot returned '#{robot_obj["error"]["message"]}'")
|
|
83
|
-
end
|
|
72
|
+
API_URL = "https://api.uptimerobot.com/v3"
|
|
73
|
+
def api_call(request_class, path, params = {})
|
|
74
|
+
uri = URI("#{API_URL}#{path}")
|
|
75
|
+
request = request_class.new(uri, "Authorization" => "Bearer #{@api_key}", "Content-Type" => "application/json")
|
|
76
|
+
request.body = params.to_json
|
|
77
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }
|
|
78
|
+
abort("An error occurred. Uptimerobot returned '#{error_message(response)}'") unless response.is_a?(Net::HTTPSuccess)
|
|
84
79
|
|
|
85
|
-
|
|
86
|
-
uri = URI(path)
|
|
87
|
-
req = request_body(uri, params)
|
|
88
|
-
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
|
89
|
-
http.request(req)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def request_body(uri, params)
|
|
94
|
-
params[:api_key] = @api_key
|
|
95
|
-
data = URI.encode_www_form params
|
|
96
|
-
req = Net::HTTP::Post.new(uri)
|
|
97
|
-
req.body = data
|
|
98
|
-
req
|
|
80
|
+
JSON.parse(response.body)
|
|
99
81
|
end
|
|
100
82
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
83
|
+
def error_message(response)
|
|
84
|
+
body = JSON.parse(response.body)
|
|
85
|
+
Array(body["message"] || body["error"] || response.body).join(", ")
|
|
86
|
+
rescue JSON::ParserError
|
|
87
|
+
response.body
|
|
104
88
|
end
|
|
105
89
|
end
|
data/lib/renuo/cli/version.rb
CHANGED
data/lib/renuo/cli.rb
CHANGED