renuo-cli 4.23.0 → 4.24.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.
- checksums.yaml +4 -4
- data/lib/renuo/cli/commands/ci/check_deploio_status.rb +29 -42
- 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: df7e7a6d263ccafd4c253e16e68a8ce4dbb489e1f726d6f8e55988fa82a3c9f3
|
|
4
|
+
data.tar.gz: be67e8df4fedb4a8e08913e2758a83ab43a4ee5e7117277db93a4fac64e6326e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf10d74c836b636236cedf3acceea7cf01ee682ef5f79d153f5d4c08a39a0d17ff8f574e3c49e6505e289ed4b178dedf2eca1ec42af1018085c3c22ab4911a34
|
|
7
|
+
data.tar.gz: 19320a9d06dd5d2d4cde92bd86c68f3d6efd5509ccfb4d18cdcebc26653f9109c0cd6fbedb9755ed68ba7744ed9d4c9a40ecf86842ea637572440fd27918c2b8
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# :
|
|
3
|
+
# simplecov:disable
|
|
4
4
|
module Renuo::Cli::Commands::Ci
|
|
5
|
-
class CheckDeploioStatus
|
|
5
|
+
class CheckDeploioStatus
|
|
6
6
|
TIMEOUT_IN_SECONDS = 600
|
|
7
7
|
INTERVAL_IN_SECONDS = 5
|
|
8
8
|
LOG_DRAIN_SECONDS = 2
|
|
9
9
|
|
|
10
10
|
command "ci check-deploio-status" do |c|
|
|
11
11
|
c.syntax = "renuo ci check-deploio-status [options] <app-name>"
|
|
12
|
-
c.summary = "Checks the build
|
|
12
|
+
c.summary = "Checks the build status of the deployment."
|
|
13
13
|
c.description = c.summary
|
|
14
14
|
c.option "-p", "--project <name>", String, "The name of the project"
|
|
15
15
|
c.option "-g", "--git-revision <hash>", String, "The Git revision"
|
|
@@ -17,13 +17,9 @@ module Renuo::Cli::Commands::Ci
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def run
|
|
20
|
-
puts "
|
|
21
|
-
|
|
22
|
-
abort "build check timed out after #{TIMEOUT_IN_SECONDS} seconds"
|
|
23
|
-
|
|
24
|
-
puts "(2/2) Checking release status for build #{build_name}..."
|
|
25
|
-
with_streamed_logs("app") { poll "release" }
|
|
26
|
-
abort "release check timed out after #{TIMEOUT_IN_SECONDS} seconds" if release.nil?
|
|
20
|
+
puts "Checking build status for revision #{@revision}..."
|
|
21
|
+
succeeded = with_streamed_build_logs { poll_build }
|
|
22
|
+
abort "build check timed out after #{TIMEOUT_IN_SECONDS} seconds" unless succeeded
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
private
|
|
@@ -42,17 +38,17 @@ module Renuo::Cli::Commands::Ci
|
|
|
42
38
|
abort unless system cmd
|
|
43
39
|
end
|
|
44
40
|
|
|
45
|
-
def
|
|
46
|
-
command = "nctl get
|
|
41
|
+
def fetch_builds
|
|
42
|
+
command = "nctl get builds -a #{@app} -p #{@project} -o yaml"
|
|
47
43
|
stdout, stderr, status = Open3.capture3 command
|
|
48
44
|
|
|
49
|
-
abort "error fetching
|
|
45
|
+
abort "error fetching build information: #{stderr}" unless status.success?
|
|
50
46
|
Psych.load_stream stdout
|
|
51
47
|
end
|
|
52
48
|
|
|
53
|
-
def
|
|
49
|
+
def with_streamed_build_logs
|
|
54
50
|
pid = Process.spawn(
|
|
55
|
-
"nctl logs application #{@app} -p #{@project} --type
|
|
51
|
+
"nctl logs application #{@app} -p #{@project} --type=build -f --lines=100 --since 15m --no-labels",
|
|
56
52
|
out: $stdout, err: $stdout
|
|
57
53
|
)
|
|
58
54
|
yield
|
|
@@ -71,63 +67,54 @@ module Renuo::Cli::Commands::Ci
|
|
|
71
67
|
end
|
|
72
68
|
|
|
73
69
|
def build
|
|
74
|
-
@build ||=
|
|
70
|
+
@build ||= fetch_builds.find do |build|
|
|
75
71
|
build.dig("spec", "forProvider", "sourceConfig", "git", "revision") == @revision
|
|
76
72
|
end
|
|
77
73
|
end
|
|
78
74
|
|
|
79
75
|
def build_name
|
|
80
|
-
|
|
76
|
+
build.dig("metadata", "name")
|
|
81
77
|
end
|
|
82
78
|
|
|
83
79
|
def build_status
|
|
84
80
|
build.dig("status", "atProvider", "buildStatus")
|
|
85
81
|
end
|
|
86
82
|
|
|
87
|
-
def
|
|
88
|
-
@release ||= fetch("releases").find do |release|
|
|
89
|
-
release.dig("spec", "forProvider", "build", "name") == build_name
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def release_status
|
|
94
|
-
release.dig("status", "atProvider", "releaseStatus")
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def succeeded?(status, type) # rubocop:disable Metrics/MethodLength
|
|
83
|
+
def build_succeeded? # rubocop:disable Metrics/MethodLength
|
|
98
84
|
time = Time.current.iso8601.to_s
|
|
99
85
|
|
|
100
|
-
case
|
|
86
|
+
case build_status
|
|
101
87
|
when "available", "success"
|
|
102
|
-
puts "#{time} #{
|
|
103
|
-
true
|
|
104
|
-
when "superseded"
|
|
105
|
-
puts "#{time} release was superseded"
|
|
88
|
+
puts "[RENUO-CLI] #{time} build #{build_name} succeeded"
|
|
106
89
|
true
|
|
107
90
|
when "paused"
|
|
108
|
-
abort "#{time} app is paused"
|
|
91
|
+
abort "[RENUO-CLI] #{time} app is paused"
|
|
109
92
|
when "error", "failed", "failure"
|
|
110
|
-
abort "#{time} #{
|
|
93
|
+
abort "[RENUO-CLI] #{time} build #{build_name} failed"
|
|
111
94
|
else
|
|
112
|
-
puts "#{time} #{
|
|
113
|
-
|
|
95
|
+
puts "[RENUO-CLI] #{time} build #{build_name} status is #{build_status}, waiting..."
|
|
96
|
+
false
|
|
114
97
|
end
|
|
115
98
|
end
|
|
116
99
|
|
|
117
|
-
def
|
|
100
|
+
def poll_build # rubocop:disable Metrics/MethodLength
|
|
118
101
|
elapsed = 0
|
|
119
102
|
|
|
120
103
|
while elapsed < TIMEOUT_IN_SECONDS
|
|
121
|
-
if
|
|
122
|
-
|
|
104
|
+
if build
|
|
105
|
+
return true if build_succeeded?
|
|
106
|
+
|
|
107
|
+
@build = nil
|
|
123
108
|
else
|
|
124
|
-
puts "no matching
|
|
109
|
+
puts "no matching build found, waiting..."
|
|
125
110
|
end
|
|
126
111
|
|
|
127
112
|
sleep INTERVAL_IN_SECONDS
|
|
128
113
|
elapsed += INTERVAL_IN_SECONDS
|
|
129
114
|
end
|
|
115
|
+
|
|
116
|
+
false
|
|
130
117
|
end
|
|
131
118
|
end
|
|
132
119
|
end
|
|
133
|
-
# :
|
|
120
|
+
# 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