uffizzi-cli 0.6.0 → 0.7.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 +14 -7
- data/exe/uffizzi +1 -1
- data/lib/uffizzi/auth_helper.rb +0 -4
- data/lib/uffizzi/cli/common.rb +2 -2
- data/lib/uffizzi/cli/config.rb +5 -11
- data/lib/uffizzi/cli/connect.rb +74 -27
- data/lib/uffizzi/cli/disconnect.rb +1 -1
- data/lib/uffizzi/cli/login.rb +2 -2
- data/lib/uffizzi/cli/logout.rb +1 -1
- data/lib/uffizzi/cli/preview/service.rb +8 -7
- data/lib/uffizzi/cli/preview.rb +66 -123
- data/lib/uffizzi/cli/project/compose.rb +14 -16
- data/lib/uffizzi/cli/project/secret.rb +19 -8
- data/lib/uffizzi/cli/project.rb +31 -7
- data/lib/uffizzi/cli.rb +15 -23
- data/lib/uffizzi/clients/api/api_client.rb +66 -21
- data/lib/uffizzi/clients/api/api_routes.rb +8 -0
- data/lib/uffizzi/clients/api/http_client.rb +47 -45
- data/lib/uffizzi/date_helper.rb +45 -0
- data/lib/uffizzi/response_helper.rb +11 -7
- data/lib/uffizzi/services/command_service.rb +9 -0
- data/lib/uffizzi/services/compose_file_service.rb +3 -0
- data/lib/uffizzi/services/preview_service.rb +109 -0
- data/lib/uffizzi/version.rb +1 -1
- data/man/uffizzi-connect +37 -0
- data/man/uffizzi-connect-acr +35 -0
- data/man/uffizzi-connect-acr.ronn +28 -0
- data/man/uffizzi-connect-docker-hub +34 -0
- data/man/uffizzi-connect-docker-hub.ronn +27 -0
- data/man/uffizzi-connect-ecr +35 -0
- data/man/uffizzi-connect-ecr.ronn +28 -0
- data/man/uffizzi-connect-gcr +40 -0
- data/man/uffizzi-connect-gcr.ronn +32 -0
- data/man/uffizzi-connect-ghcr +35 -0
- data/man/uffizzi-connect-ghcr.ronn +28 -0
- data/man/uffizzi-connect.ronn +31 -0
- data/man/uffizzi-disconnect +37 -0
- data/man/uffizzi-disconnect.ronn +31 -0
- data/man/uffizzi-login +1 -1
- data/man/uffizzi-login.ronn +1 -1
- data/man/uffizzi-preview-update +34 -0
- data/man/uffizzi-preview-update.ronn +33 -0
- data/man/uffizzi-project-set-default +34 -0
- data/man/uffizzi-project-set-default.html +111 -0
- data/man/uffizzi-project-set-default.ronn +26 -0
- metadata +23 -2
@@ -8,20 +8,42 @@ module ApiClient
|
|
8
8
|
|
9
9
|
def create_session(server, params = {})
|
10
10
|
uri = session_uri(server)
|
11
|
-
response =
|
11
|
+
response = http_client.make_post_request(uri, params)
|
12
12
|
|
13
13
|
build_response(response)
|
14
14
|
end
|
15
15
|
|
16
16
|
def destroy_session(server)
|
17
17
|
uri = session_uri(server)
|
18
|
-
response =
|
18
|
+
response = http_client.make_delete_request(uri)
|
19
19
|
|
20
20
|
build_response(response)
|
21
21
|
end
|
22
22
|
|
23
23
|
def fetch_projects(server)
|
24
24
|
uri = projects_uri(server)
|
25
|
+
response = http_client.make_get_request(uri)
|
26
|
+
|
27
|
+
build_response(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
def fetch_credentials(server)
|
31
|
+
uri = credentials_uri(server)
|
32
|
+
|
33
|
+
response = http_client.make_get_request(uri)
|
34
|
+
|
35
|
+
build_response(response)
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_credential(server, type)
|
39
|
+
uri = check_credential_uri(server, type)
|
40
|
+
response = http_client.make_get_request(uri)
|
41
|
+
|
42
|
+
build_response(response)
|
43
|
+
end
|
44
|
+
|
45
|
+
def describe_project(server, project_slug)
|
46
|
+
uri = project_uri(server, project_slug)
|
25
47
|
response = Uffizzi::HttpClient.make_get_request(uri)
|
26
48
|
|
27
49
|
build_response(response)
|
@@ -29,132 +51,154 @@ module ApiClient
|
|
29
51
|
|
30
52
|
def create_credential(server, params)
|
31
53
|
uri = credentials_uri(server)
|
32
|
-
response =
|
54
|
+
response = http_client.make_post_request(uri, params)
|
33
55
|
|
34
56
|
build_response(response)
|
35
57
|
end
|
36
58
|
|
37
59
|
def fetch_deployment_services(server, project_slug, deployment_id)
|
38
60
|
uri = preview_services_uri(server, project_slug, deployment_id)
|
39
|
-
response =
|
61
|
+
response = http_client.make_get_request(uri)
|
40
62
|
|
41
63
|
build_response(response)
|
42
64
|
end
|
43
65
|
|
44
66
|
def delete_credential(server, credential_type)
|
45
67
|
uri = delete_credential_uri(server, credential_type)
|
46
|
-
response =
|
68
|
+
response = http_client.make_delete_request(uri)
|
47
69
|
|
48
70
|
build_response(response)
|
49
71
|
end
|
50
72
|
|
51
73
|
def fetch_deployment_service_logs(server, project_slug, deployment_id, container_name)
|
52
74
|
uri = preview_service_logs_uri(server, project_slug, deployment_id, container_name)
|
53
|
-
response =
|
75
|
+
response = http_client.make_get_request(uri)
|
54
76
|
|
55
77
|
build_response(response)
|
56
78
|
end
|
57
79
|
|
58
80
|
def set_compose_file(server, params, project_slug)
|
59
81
|
uri = compose_file_uri(server, project_slug)
|
60
|
-
response =
|
82
|
+
response = http_client.make_post_request(uri, params)
|
61
83
|
|
62
84
|
build_response(response)
|
63
85
|
end
|
64
86
|
|
65
87
|
def unset_compose_file(server, project_slug)
|
66
88
|
uri = compose_file_uri(server, project_slug)
|
67
|
-
response =
|
89
|
+
response = http_client.make_delete_request(uri)
|
68
90
|
|
69
91
|
build_response(response)
|
70
92
|
end
|
71
93
|
|
72
94
|
def fetch_secrets(server, project_slug)
|
73
95
|
uri = secrets_uri(server, project_slug)
|
74
|
-
response =
|
96
|
+
response = http_client.make_get_request(uri)
|
75
97
|
|
76
98
|
build_response(response)
|
77
99
|
end
|
78
100
|
|
79
101
|
def bulk_create_secrets(server, project_slug, params)
|
80
102
|
uri = "#{secrets_uri(server, project_slug)}/bulk_create"
|
81
|
-
response =
|
103
|
+
response = http_client.make_post_request(uri, params)
|
82
104
|
|
83
105
|
build_response(response)
|
84
106
|
end
|
85
107
|
|
86
108
|
def delete_secret(server, project_slug, id)
|
87
109
|
uri = secret_uri(server, project_slug, id)
|
88
|
-
response =
|
110
|
+
response = http_client.make_delete_request(uri)
|
89
111
|
|
90
112
|
build_response(response)
|
91
113
|
end
|
92
114
|
|
93
115
|
def describe_compose_file(server, project_slug)
|
94
116
|
uri = compose_file_uri(server, project_slug)
|
95
|
-
response =
|
117
|
+
response = http_client.make_get_request(uri)
|
96
118
|
|
97
119
|
build_response(response)
|
98
120
|
end
|
99
121
|
|
100
122
|
def validate_compose_file(server, project_slug)
|
101
123
|
uri = validate_compose_file_uri(server, project_slug)
|
102
|
-
response =
|
124
|
+
response = http_client.make_get_request(uri)
|
103
125
|
|
104
126
|
build_response(response)
|
105
127
|
end
|
106
128
|
|
107
129
|
def fetch_deployments(server, project_slug)
|
108
130
|
uri = deployments_uri(server, project_slug)
|
109
|
-
response =
|
131
|
+
response = http_client.make_get_request(uri)
|
110
132
|
|
111
133
|
build_response(response)
|
112
134
|
end
|
113
135
|
|
114
136
|
def create_deployment(server, project_slug, params)
|
115
137
|
uri = deployments_uri(server, project_slug)
|
116
|
-
response =
|
138
|
+
response = http_client.make_post_request(uri, params)
|
139
|
+
|
140
|
+
build_response(response)
|
141
|
+
end
|
142
|
+
|
143
|
+
def update_deployment(server, project_slug, deployment_id, params)
|
144
|
+
uri = deployment_uri(server, project_slug, deployment_id)
|
145
|
+
response = http_client.make_put_request(uri, params)
|
117
146
|
|
118
147
|
build_response(response)
|
119
148
|
end
|
120
149
|
|
121
150
|
def delete_deployment(server, project_slug, deployment_id)
|
122
151
|
uri = deployment_uri(server, project_slug, deployment_id)
|
123
|
-
response =
|
152
|
+
response = http_client.make_delete_request(uri)
|
124
153
|
|
125
154
|
build_response(response)
|
126
155
|
end
|
127
156
|
|
128
157
|
def describe_deployment(server, project_slug, deployment_id)
|
129
158
|
uri = deployment_uri(server, project_slug, deployment_id)
|
130
|
-
response =
|
159
|
+
response = http_client.make_get_request(uri)
|
131
160
|
|
132
161
|
build_response(response)
|
133
162
|
end
|
134
163
|
|
135
164
|
def fetch_events(server, project_slug, deployment_id)
|
136
165
|
uri = events_uri(server, project_slug, deployment_id)
|
137
|
-
response =
|
166
|
+
response = http_client.make_get_request(uri)
|
138
167
|
|
139
168
|
build_response(response)
|
140
169
|
end
|
141
170
|
|
142
171
|
def get_activity_items(server, project_slug, deployment_id)
|
143
172
|
uri = activity_items_uri(server, project_slug, deployment_id)
|
144
|
-
response =
|
173
|
+
response = http_client.make_get_request(uri)
|
145
174
|
|
146
175
|
build_response(response)
|
147
176
|
end
|
148
177
|
|
149
178
|
def deploy_containers(server, project_slug, deployment_id, params)
|
150
179
|
uri = deploy_containers_uri(server, project_slug, deployment_id)
|
151
|
-
response =
|
180
|
+
response = http_client.make_post_request(uri, params)
|
152
181
|
|
153
182
|
build_response(response)
|
154
183
|
end
|
155
184
|
|
156
185
|
private
|
157
186
|
|
187
|
+
def http_client
|
188
|
+
if @http_client.nil?
|
189
|
+
params = {}
|
190
|
+
if Uffizzi::ConfigFile.exists?
|
191
|
+
params[:cookie] = Uffizzi::ConfigFile.read_option(:cookie)
|
192
|
+
params[:basic_auth_user] = Uffizzi::ConfigFile.read_option(:basic_auth_user)
|
193
|
+
params[:basic_auth_password] = Uffizzi::ConfigFile.read_option(:basic_auth_password)
|
194
|
+
end
|
195
|
+
|
196
|
+
@http_client = Uffizzi::HttpClient.new(params[:cookie], params[:basic_auth_user], params[:basic_auth_password])
|
197
|
+
end
|
198
|
+
|
199
|
+
@http_client
|
200
|
+
end
|
201
|
+
|
158
202
|
def build_response(response)
|
159
203
|
{
|
160
204
|
body: response_body(response),
|
@@ -164,7 +208,7 @@ module ApiClient
|
|
164
208
|
end
|
165
209
|
|
166
210
|
def response_body(response)
|
167
|
-
return nil if response.body.nil?
|
211
|
+
return nil if response.body.nil? || response.body.empty?
|
168
212
|
|
169
213
|
JSON.parse(response.body, symbolize_names: true)
|
170
214
|
rescue JSON::ParserError
|
@@ -178,6 +222,7 @@ module ApiClient
|
|
178
222
|
cookie_content = cookies.first
|
179
223
|
cookie = cookie_content.split(';').first
|
180
224
|
Uffizzi::ConfigFile.rewrite_cookie(cookie) if Uffizzi::ConfigFile.exists?
|
225
|
+
http_client.auth_cookie = cookie
|
181
226
|
|
182
227
|
cookie
|
183
228
|
end
|
@@ -7,6 +7,10 @@ module ApiRoutes
|
|
7
7
|
"#{server}/api/cli/v1/projects/#{project_slug}/compose_file"
|
8
8
|
end
|
9
9
|
|
10
|
+
def project_uri(server, project_slug)
|
11
|
+
"#{server}/api/cli/v1/projects/#{project_slug}"
|
12
|
+
end
|
13
|
+
|
10
14
|
def projects_uri(server)
|
11
15
|
"#{server}/api/cli/v1/projects"
|
12
16
|
end
|
@@ -48,6 +52,10 @@ module ApiRoutes
|
|
48
52
|
"#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/events"
|
49
53
|
end
|
50
54
|
|
55
|
+
def check_credential_uri(server, type)
|
56
|
+
"#{server}/api/cli/v1/account/credentials/#{type}/check_credential"
|
57
|
+
end
|
58
|
+
|
51
59
|
def credentials_uri(server)
|
52
60
|
"#{server}/api/cli/v1/account/credentials"
|
53
61
|
end
|
@@ -2,67 +2,69 @@
|
|
2
2
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'json'
|
5
|
-
require 'uffizzi/config_file'
|
6
|
-
require 'uffizzi/response_helper'
|
7
5
|
|
8
6
|
module Uffizzi
|
9
7
|
class HttpClient
|
10
|
-
|
11
|
-
def make_get_request(request_uri, cookies_required = true)
|
12
|
-
make_request(:get, request_uri, cookies_required)
|
13
|
-
end
|
8
|
+
attr_accessor :auth_cookie, :basic_auth_user, :basic_auth_password
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
def initialize(auth_cookie, basic_auth_user, basic_auth_password)
|
11
|
+
@auth_cookie = auth_cookie
|
12
|
+
@basic_auth_user = basic_auth_user
|
13
|
+
@basic_auth_password = basic_auth_password
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
def make_get_request(request_uri)
|
17
|
+
make_request(:get, request_uri)
|
18
|
+
end
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def make_post_request(request_uri, params = {})
|
21
|
+
make_request(:post, request_uri, params)
|
22
|
+
end
|
26
23
|
|
27
|
-
|
24
|
+
def make_put_request(request_uri, params = {})
|
25
|
+
make_request(:put, request_uri, params)
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def make_delete_request(request_uri)
|
29
|
+
make_request(:delete, request_uri)
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
request = build_request(uri, params, method, require_cookies)
|
32
|
+
private
|
35
33
|
|
36
|
-
|
37
|
-
|
34
|
+
def make_request(method, request_uri, params = {})
|
35
|
+
uri = URI(request_uri)
|
36
|
+
use_ssl = request_uri.start_with?('https')
|
38
37
|
|
39
|
-
|
38
|
+
response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
|
39
|
+
request = build_request(uri, params, method)
|
40
40
|
|
41
|
-
|
41
|
+
http.request(request)
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
Net::HTTP::Get.new(uri.path, headers)
|
49
|
-
when :post
|
50
|
-
Net::HTTP::Post.new(uri.path, headers)
|
51
|
-
when :delete
|
52
|
-
Net::HTTP::Delete.new(uri.path, headers)
|
53
|
-
when :put
|
54
|
-
Net::HTTP::Put.new(uri.path, headers)
|
55
|
-
end
|
56
|
-
if request.instance_of?(Net::HTTP::Post)
|
57
|
-
request.body = params.to_json
|
58
|
-
end
|
59
|
-
request['Cookie'] = ConfigFile.read_option(:cookie) if require_cookies
|
60
|
-
if ConfigFile.exists? && ConfigFile.option_has_value?(:basic_auth_user) && ConfigFile.option_has_value?(:basic_auth_password)
|
61
|
-
request.basic_auth(ConfigFile.read_option(:basic_auth_user), ConfigFile.read_option(:basic_auth_password))
|
62
|
-
end
|
44
|
+
raise Uffizzi::Error.new('Not authorized') if response.is_a?(Net::HTTPUnauthorized)
|
45
|
+
|
46
|
+
response
|
47
|
+
end
|
63
48
|
|
64
|
-
|
49
|
+
def build_request(uri, params, method)
|
50
|
+
headers = { 'Content-Type' => 'application/json' }
|
51
|
+
request = case method
|
52
|
+
when :get
|
53
|
+
Net::HTTP::Get.new(uri.path, headers)
|
54
|
+
when :post
|
55
|
+
Net::HTTP::Post.new(uri.path, headers)
|
56
|
+
when :delete
|
57
|
+
Net::HTTP::Delete.new(uri.path, headers)
|
58
|
+
when :put
|
59
|
+
Net::HTTP::Put.new(uri.path, headers)
|
60
|
+
end
|
61
|
+
if request.instance_of?(Net::HTTP::Post) || request.instance_of?(Net::HTTP::Put)
|
62
|
+
request.body = params.to_json
|
65
63
|
end
|
64
|
+
request['Cookie'] = @auth_cookie
|
65
|
+
request.basic_auth(@basic_auth_user, @basic_auth_password)
|
66
|
+
|
67
|
+
request
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Uffizzi
|
6
|
+
module DateHelper
|
7
|
+
TWO_MINUTES = 120
|
8
|
+
TWO_HOURS = 120
|
9
|
+
TWO_DAYS = 48
|
10
|
+
TWO_WEEKS = 14
|
11
|
+
TWO_MONTHS = (365 / 12 * 2)
|
12
|
+
TWO_YEARS = 730
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def count_distanse(now, previous_date)
|
16
|
+
seconds = (now - previous_date).round
|
17
|
+
return convert_to_words(seconds, 'seconds') if seconds < TWO_MINUTES
|
18
|
+
|
19
|
+
minutes = seconds / 60
|
20
|
+
return convert_to_words(minutes, 'minutes') if minutes < TWO_HOURS
|
21
|
+
|
22
|
+
hours = minutes / 60
|
23
|
+
return convert_to_words(hours, 'hours') if hours < TWO_DAYS
|
24
|
+
|
25
|
+
days = hours / 24
|
26
|
+
return convert_to_words(days, 'days') if days < TWO_WEEKS
|
27
|
+
|
28
|
+
weeks = days / 7
|
29
|
+
return convert_to_words(weeks, 'weeks') if days < TWO_MONTHS
|
30
|
+
|
31
|
+
months = (days / (365 / 12)).round
|
32
|
+
return convert_to_words(months, 'months') if days < TWO_YEARS
|
33
|
+
|
34
|
+
years = days / 365
|
35
|
+
convert_to_words(years, 'years')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def convert_to_words(value, unit)
|
41
|
+
"#{value} #{unit} ago"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -28,22 +28,26 @@ module Uffizzi
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def handle_failed_response(response)
|
31
|
-
|
31
|
+
prepared_errors = prepare_errors(response[:body][:errors])
|
32
|
+
raise Uffizzi::Error.new(prepared_errors)
|
32
33
|
end
|
33
34
|
|
34
35
|
def handle_invalid_compose_response(response)
|
35
|
-
|
36
|
+
prepared_errors = prepare_errors(response[:body][:compose_file][:payload][:errors])
|
37
|
+
raise Uffizzi::Error.new(prepared_errors)
|
36
38
|
end
|
37
39
|
|
38
40
|
private
|
39
41
|
|
40
|
-
def
|
41
|
-
errors.
|
42
|
-
if
|
43
|
-
|
42
|
+
def prepare_errors(errors)
|
43
|
+
errors.values.reduce('') do |acc, error_messages|
|
44
|
+
if error_messages.is_a?(Array)
|
45
|
+
error_messages.each { |error_message| acc = "#{acc}#{error_message}\n" }
|
44
46
|
else
|
45
|
-
|
47
|
+
acc = "#{acc}#{error_messages}\n"
|
46
48
|
end
|
49
|
+
|
50
|
+
acc
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -29,6 +29,9 @@ class ComposeFileService
|
|
29
29
|
content: Base64.encode64(dependency_file_data),
|
30
30
|
}
|
31
31
|
end
|
32
|
+
rescue Errno::ENOENT => e
|
33
|
+
dependency_path = e.message.split('- ').last
|
34
|
+
raise Uffizzi::Error.new("The config file #{dependency_path} does not exist")
|
32
35
|
end
|
33
36
|
|
34
37
|
def fetch_configs(configs_data)
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'uffizzi/clients/api/api_client'
|
4
|
+
|
3
5
|
class PreviewService
|
4
6
|
class << self
|
7
|
+
include ApiClient
|
5
8
|
def read_deployment_id(deployment_name)
|
6
9
|
return nil unless deployment_name.start_with?('deployment-')
|
7
10
|
return nil unless deployment_name.split('-').size == 2
|
@@ -11,5 +14,111 @@ class PreviewService
|
|
11
14
|
|
12
15
|
deployment_id
|
13
16
|
end
|
17
|
+
|
18
|
+
def start_deploy_containers(project_slug, deployment, success_message)
|
19
|
+
deployment_id = deployment[:id]
|
20
|
+
params = { id: deployment_id }
|
21
|
+
|
22
|
+
response = deploy_containers(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment_id, params)
|
23
|
+
|
24
|
+
if Uffizzi::ResponseHelper.no_content?(response)
|
25
|
+
Uffizzi.ui.say(success_message)
|
26
|
+
create_deployment(deployment, project_slug)
|
27
|
+
else
|
28
|
+
Uffizzi::ResponseHelper.handle_failed_response(response)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_deployment(deployment, project_slug)
|
35
|
+
spinner = TTY::Spinner.new('[:spinner] Creating containers...', format: :dots)
|
36
|
+
spinner.auto_spin
|
37
|
+
|
38
|
+
activity_items = []
|
39
|
+
loop do
|
40
|
+
response = get_activity_items(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment[:id])
|
41
|
+
handle_activity_items_response(response, spinner)
|
42
|
+
activity_items = response[:body][:activity_items]
|
43
|
+
break if activity_items.count == deployment[:containers].count
|
44
|
+
|
45
|
+
sleep(5)
|
46
|
+
end
|
47
|
+
|
48
|
+
spinner.success
|
49
|
+
|
50
|
+
Uffizzi.ui.say('Done')
|
51
|
+
|
52
|
+
display_containers_deploying_status(deployment, project_slug, activity_items)
|
53
|
+
end
|
54
|
+
|
55
|
+
def display_containers_deploying_status(deployment, project_slug, activity_items)
|
56
|
+
spinner = TTY::Spinner::Multi.new('[:spinner] Deploying preview...', format: :dots, style: {
|
57
|
+
middle: ' ',
|
58
|
+
bottom: ' ',
|
59
|
+
})
|
60
|
+
|
61
|
+
containers_spinners = create_containers_spinners(activity_items, spinner)
|
62
|
+
|
63
|
+
loop do
|
64
|
+
response = get_activity_items(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment[:id])
|
65
|
+
handle_activity_items_response(response, spinner)
|
66
|
+
activity_items = response[:body][:activity_items]
|
67
|
+
check_activity_items_state(activity_items, containers_spinners)
|
68
|
+
break if activity_items.all? { |activity_item| activity_item[:state] == 'deployed' || activity_item[:state] == 'failed' }
|
69
|
+
|
70
|
+
sleep(5)
|
71
|
+
end
|
72
|
+
|
73
|
+
if Uffizzi.ui.output_format.nil?
|
74
|
+
Uffizzi.ui.say('Done')
|
75
|
+
preview_url = "https://#{deployment[:preview_url]}"
|
76
|
+
Uffizzi.ui.say(preview_url) if spinner.success?
|
77
|
+
else
|
78
|
+
output_data = build_output_data(deployment)
|
79
|
+
Uffizzi.ui.output(output_data)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def create_containers_spinners(activity_items, spinner)
|
84
|
+
activity_items.map do |activity_item|
|
85
|
+
container_spinner = spinner.register("[:spinner] #{activity_item[:name]}")
|
86
|
+
container_spinner.auto_spin
|
87
|
+
{
|
88
|
+
name: activity_item[:name],
|
89
|
+
spinner: container_spinner,
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def check_activity_items_state(activity_items, containers_spinners)
|
95
|
+
finished_activity_items = activity_items.filter do |activity_item|
|
96
|
+
activity_item[:state] == 'deployed' || activity_item[:state] == 'failed'
|
97
|
+
end
|
98
|
+
finished_activity_items.each do |activity_item|
|
99
|
+
container_spinner = containers_spinners.detect { |spinner| spinner[:name] == activity_item[:name] }
|
100
|
+
spinner = container_spinner[:spinner]
|
101
|
+
case activity_item[:state]
|
102
|
+
when 'deployed'
|
103
|
+
spinner.success
|
104
|
+
when 'failed'
|
105
|
+
spinner.error
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def handle_activity_items_response(response, spinner)
|
111
|
+
unless Uffizzi::ResponseHelper.ok?(response)
|
112
|
+
spinner.error
|
113
|
+
Uffizzi::ResponseHelper.handle_failed_response(response)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def build_output_data(output_data)
|
118
|
+
{
|
119
|
+
id: "deployment-#{output_data[:id]}",
|
120
|
+
url: "https://#{output_data[:preview_url]}",
|
121
|
+
}
|
122
|
+
end
|
14
123
|
end
|
15
124
|
end
|
data/lib/uffizzi/version.rb
CHANGED
data/man/uffizzi-connect
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
.\" generated with Ronn-NG/v0.9.1
|
2
|
+
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
+
.TH "UFFIZZI\-CONNECT" "" "April 2022" ""
|
4
|
+
.SH "NAME"
|
5
|
+
\fBuffizzi\-connect\fR \- grant a Uffizzi user account access to external services
|
6
|
+
.SH "SYNOPSIS"
|
7
|
+
.nf
|
8
|
+
uffizzi connect COMMAND
|
9
|
+
.fi
|
10
|
+
.SH "DESCRIPTION"
|
11
|
+
.nf
|
12
|
+
Grants a Uffizzi user account access to external services
|
13
|
+
|
14
|
+
For more information on connecting to external services, see:
|
15
|
+
https://docs\.uffizzi\.com/cli
|
16
|
+
.fi
|
17
|
+
.SH "COMMANDS"
|
18
|
+
.nf
|
19
|
+
COMMAND is one of the following:
|
20
|
+
|
21
|
+
acr
|
22
|
+
Connect to Azure Container Registry (azurecr\.io)\.
|
23
|
+
|
24
|
+
docker\-hub
|
25
|
+
Connect to Docker Hub (hub\.docker\.com)\.
|
26
|
+
|
27
|
+
ecr
|
28
|
+
Connect to Amazon Elastic Container Registry (amazonaws\.com)\.
|
29
|
+
|
30
|
+
gcr
|
31
|
+
Connect to Google Container Registry (gcr\.io)\.
|
32
|
+
|
33
|
+
gchr
|
34
|
+
Connect to GitHub Container Registry (ghcr\.io)\.
|
35
|
+
.fi
|
36
|
+
.P
|
37
|
+
Run \'uffizzi connect COMMAND \-\-help\' for more information on a command\.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
.\" generated with Ronn-NG/v0.9.1
|
2
|
+
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
+
.TH "UFFIZZI\-CONNECT\-ACR" "" "April 2022" ""
|
4
|
+
.SH "NAME"
|
5
|
+
\fBuffizzi\-connect\-acr\fR \- grant a Uffizzi user account access to a private Azure Container Registry (ACR)
|
6
|
+
.SH "SYNOPSIS"
|
7
|
+
.nf
|
8
|
+
uffizzi connect acr
|
9
|
+
.fi
|
10
|
+
.SH "DESCRIPTION"
|
11
|
+
.nf
|
12
|
+
Given valid credentials, grants a Uffizzi user account access
|
13
|
+
to a private Azure Container Registry
|
14
|
+
|
15
|
+
This command can fail for the following reasons:
|
16
|
+
\- The active user does not have permission to connect
|
17
|
+
external services\.
|
18
|
+
\- The given credentials are invalid\.
|
19
|
+
|
20
|
+
For more information on connecting to external services, see:
|
21
|
+
https://docs\.uffizzi\.com/cli
|
22
|
+
|
23
|
+
For detailed instructions on configuring webhooks to send push
|
24
|
+
notifications to Uffizzi, see
|
25
|
+
https://docs\.uffizzi\.com/guides/container\-registry\-integrations
|
26
|
+
.fi
|
27
|
+
.SH "EXAMPLES"
|
28
|
+
.nf
|
29
|
+
The following command will prompt the user to enter ACR
|
30
|
+
credentials, including registry domain, Docker ID and
|
31
|
+
password or access token:
|
32
|
+
|
33
|
+
$ uffizzi connect acr
|
34
|
+
.fi
|
35
|
+
|