uffizzi-cli 0.11.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/uffizzi.rb +1 -0
- data/lib/uffizzi/cli/connect.rb +95 -46
- data/lib/uffizzi/cli/disconnect.rb +5 -2
- data/lib/uffizzi/cli/login.rb +11 -6
- data/lib/uffizzi/cli/login_by_identity_token.rb +47 -0
- data/lib/uffizzi/cli/preview.rb +95 -34
- data/lib/uffizzi/cli/project.rb +3 -1
- data/lib/uffizzi/cli.rb +8 -0
- data/lib/uffizzi/clients/api/api_client.rb +21 -14
- data/lib/uffizzi/clients/api/api_routes.rb +18 -8
- data/lib/uffizzi/clients/api/http_client.rb +4 -4
- data/lib/uffizzi/helpers/connect_helper.rb +45 -0
- data/lib/uffizzi/services/project_service.rb +1 -0
- data/lib/uffizzi/version.rb +1 -1
- data/man/uffizzi-connect +30 -31
- data/man/uffizzi-connect-acr +27 -25
- data/man/uffizzi-connect-acr.ronn +33 -19
- data/man/uffizzi-connect-docker-hub +24 -24
- data/man/uffizzi-connect-docker-hub.ronn +30 -18
- data/man/uffizzi-connect-docker-registry +37 -0
- data/man/uffizzi-connect-docker-registry.ronn +41 -0
- data/man/uffizzi-connect-ecr +27 -25
- data/man/uffizzi-connect-ecr.ronn +33 -19
- data/man/uffizzi-connect-gcr +20 -29
- data/man/uffizzi-connect-gcr.ronn +26 -22
- data/man/uffizzi-connect-ghcr +23 -33
- data/man/uffizzi-connect-ghcr.ronn +27 -23
- data/man/uffizzi-connect.ronn +28 -20
- data/man/uffizzi-login-by-identity-token +29 -0
- data/man/uffizzi-login-by-identity-token.html +106 -0
- data/man/uffizzi-login-by-identity-token.ronn +21 -0
- data/man/uffizzi-preview-create +16 -1
- data/man/uffizzi-preview-create.ronn +14 -0
- data/man/uffizzi-preview-list +25 -1
- data/man/uffizzi-preview-list.ronn +23 -0
- data/man/uffizzi-preview-update +20 -2
- data/man/uffizzi-preview-update.ronn +17 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac2d58dae4db13ed788532732a92f9d4a317780cb4b80ef07d185f899d10749d
|
4
|
+
data.tar.gz: a1b4b37db41936eabb930febe701186027a80d0684ca371ed442168caecea779
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2420a93b4b17a5efb2de11ed5a998070da7eb2f8f22a2d09bf2598b4eb88841f428f0a87cf7de7c5b49e289f12f2d85413aa96600ca3726b71b5ec962e6b68c
|
7
|
+
data.tar.gz: 2dff8bd8e614d8ffaad6a2b42f528844c5a6d1232c2327bcb756c8ae6d4b014e3b310965f01fd86dc2d6eb40cb9aaab10755ef707a0dc808538620581b1f09cb
|
data/config/uffizzi.rb
CHANGED
@@ -19,6 +19,7 @@ module Uffizzi
|
|
19
19
|
google: 'UffizziCore::Credential::Google',
|
20
20
|
amazon: 'UffizziCore::Credential::Amazon',
|
21
21
|
github_registry: 'UffizziCore::Credential::GithubContainerRegistry',
|
22
|
+
docker_registry: 'UffizziCore::Credential::DockerRegistry',
|
22
23
|
}
|
23
24
|
config.default_server = 'app.uffizzi.com'
|
24
25
|
end
|
data/lib/uffizzi/cli/connect.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'uffizzi'
|
4
|
+
require 'uffizzi/helpers/connect_helper'
|
4
5
|
|
5
6
|
module Uffizzi
|
6
7
|
class Cli::Connect < Thor
|
@@ -9,7 +10,8 @@ module Uffizzi
|
|
9
10
|
desc 'list-credentials', 'List existing credentials for an account'
|
10
11
|
def list_credentials
|
11
12
|
server = ConfigFile.read_option(:server)
|
12
|
-
|
13
|
+
account_id = ConfigFile.read_option(:account_id)
|
14
|
+
response = fetch_credentials(server, account_id)
|
13
15
|
if ResponseHelper.ok?(response)
|
14
16
|
handle_list_credentials_success(response)
|
15
17
|
else
|
@@ -21,42 +23,77 @@ module Uffizzi
|
|
21
23
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
22
24
|
desc: 'Skip raising an error within check the credential'
|
23
25
|
method_option :update_credential_if_exists, type: :boolean, default: false
|
26
|
+
method_option :username, type: :string, aliases: :u
|
27
|
+
method_option :password, type: :string, aliases: :p
|
24
28
|
def docker_hub
|
25
29
|
type = Uffizzi.configuration.credential_types[:dockerhub]
|
26
30
|
credential_exists = credential_exists?(type)
|
27
31
|
handle_existing_credential_options('docker-hub') if credential_exists
|
28
32
|
|
29
|
-
username =
|
30
|
-
password = ENV['DOCKERHUB_PASSWORD'] || Uffizzi.ui.ask('Password:', echo: false)
|
33
|
+
username, password = Uffizzi::ConnectHelper.get_docker_hub_data(options)
|
31
34
|
|
32
35
|
params = {
|
33
36
|
username: username,
|
34
37
|
password: password,
|
35
38
|
type: type,
|
36
39
|
}
|
40
|
+
server = ConfigFile.read_option(:server)
|
41
|
+
account_id = ConfigFile.read_option(:account_id)
|
42
|
+
|
43
|
+
response = if credential_exists
|
44
|
+
update_credential(server, account_id, params, type)
|
45
|
+
else
|
46
|
+
create_credential(server, account_id, params)
|
47
|
+
end
|
48
|
+
|
49
|
+
handle_result_for('Docker Hub', response)
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'docker-registry', 'Connect to any registry implementing the Docker Registry HTTP API protocol'
|
53
|
+
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
54
|
+
desc: 'Skip raising an error within check the credential'
|
55
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
56
|
+
method_option :registry, type: :string, aliases: :r
|
57
|
+
method_option :username, type: :string, aliases: :u
|
58
|
+
method_option :password, type: :string, aliases: :p
|
59
|
+
def docker_registry
|
60
|
+
type = Uffizzi.configuration.credential_types[:docker_registry]
|
61
|
+
credential_exists = credential_exists?(type)
|
62
|
+
handle_existing_credential_options('docker-registry') if credential_exists
|
63
|
+
|
64
|
+
registry_url, username, password = Uffizzi::ConnectHelper.get_docker_registry_data(options)
|
37
65
|
|
66
|
+
params = {
|
67
|
+
registry_url: prepare_registry_url(registry_url),
|
68
|
+
username: username,
|
69
|
+
password: password,
|
70
|
+
type: type,
|
71
|
+
}
|
38
72
|
server = ConfigFile.read_option(:server)
|
39
|
-
|
73
|
+
account_id = ConfigFile.read_option(:account_id)
|
40
74
|
|
41
|
-
if
|
42
|
-
|
75
|
+
response = if credential_exists
|
76
|
+
update_credential(server, account_id, params, type)
|
43
77
|
else
|
44
|
-
|
78
|
+
create_credential(server, account_id, params)
|
45
79
|
end
|
80
|
+
|
81
|
+
handle_result_for('Docker Registry', response)
|
46
82
|
end
|
47
83
|
|
48
84
|
desc 'acr', 'Connect to Azure Container Registry (azurecr.io)'
|
49
85
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
50
86
|
desc: 'Skip raising an error within check the credential'
|
51
87
|
method_option :update_credential_if_exists, type: :boolean, default: false
|
88
|
+
method_option :registry, type: :string, aliases: :r
|
89
|
+
method_option :username, type: :string, aliases: :u
|
90
|
+
method_option :password, type: :string, aliases: :p
|
52
91
|
def acr
|
53
92
|
type = Uffizzi.configuration.credential_types[:azure]
|
54
93
|
credential_exists = credential_exists?(type)
|
55
94
|
handle_existing_credential_options('acr') if credential_exists
|
56
95
|
|
57
|
-
registry_url
|
58
|
-
username = ENV['ACR_USERNAME'] || Uffizzi.ui.ask('Docker ID:')
|
59
|
-
password = ENV['ACR_PASSWORD'] || Uffizzi.ui.ask('Password/Access Token:', echo: false)
|
96
|
+
registry_url, username, password = Uffizzi::ConnectHelper.get_acr_data(options)
|
60
97
|
|
61
98
|
params = {
|
62
99
|
username: username,
|
@@ -64,45 +101,48 @@ module Uffizzi
|
|
64
101
|
registry_url: prepare_registry_url(registry_url),
|
65
102
|
type: type,
|
66
103
|
}
|
67
|
-
|
68
104
|
server = ConfigFile.read_option(:server)
|
69
|
-
|
105
|
+
account_id = ConfigFile.read_option(:account_id)
|
70
106
|
|
71
|
-
if
|
72
|
-
|
107
|
+
response = if credential_exists
|
108
|
+
update_credential(server, account_id, params, type)
|
73
109
|
else
|
74
|
-
|
110
|
+
create_credential(server, account_id, params)
|
75
111
|
end
|
112
|
+
|
113
|
+
handle_result_for('ACR', response)
|
76
114
|
end
|
77
115
|
|
78
116
|
desc 'ecr', 'Connect to Amazon Elastic Container Registry'
|
79
117
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
80
118
|
desc: 'Skip raising an error within check the credential'
|
81
119
|
method_option :update_credential_if_exists, type: :boolean, default: false
|
120
|
+
method_option :registry, type: :string, aliases: :r
|
121
|
+
method_option :id, type: :string
|
122
|
+
method_option :secret, type: :string, aliases: :s
|
82
123
|
def ecr
|
83
124
|
type = Uffizzi.configuration.credential_types[:amazon]
|
84
125
|
credential_exists = credential_exists?(type)
|
85
126
|
handle_existing_credential_options('ecr') if credential_exists
|
86
127
|
|
87
|
-
registry_url
|
88
|
-
access_key = ENV['AWS_ACCESS_KEY_ID'] || Uffizzi.ui.ask('Access key ID:')
|
89
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || Uffizzi.ui.ask('Secret access key:', echo: false)
|
128
|
+
registry_url, access_key_id, secret_access_key = Uffizzi::ConnectHelper.get_ecr_data(options)
|
90
129
|
|
91
130
|
params = {
|
92
|
-
username:
|
131
|
+
username: access_key_id,
|
93
132
|
password: secret_access_key,
|
94
133
|
registry_url: prepare_registry_url(registry_url),
|
95
134
|
type: type,
|
96
135
|
}
|
97
|
-
|
98
136
|
server = ConfigFile.read_option(:server)
|
99
|
-
|
137
|
+
account_id = ConfigFile.read_option(:account_id)
|
100
138
|
|
101
|
-
if
|
102
|
-
|
139
|
+
response = if credential_exists
|
140
|
+
update_credential(server, account_id, params, type)
|
103
141
|
else
|
104
|
-
|
142
|
+
create_credential(server, account_id, params)
|
105
143
|
end
|
144
|
+
|
145
|
+
handle_result_for('ECR', response)
|
106
146
|
end
|
107
147
|
|
108
148
|
desc 'gcr', 'Connect to Google Container Registry (gcr.io)'
|
@@ -120,15 +160,16 @@ module Uffizzi
|
|
120
160
|
password: credential_content,
|
121
161
|
type: type,
|
122
162
|
}
|
123
|
-
|
124
163
|
server = ConfigFile.read_option(:server)
|
125
|
-
|
164
|
+
account_id = ConfigFile.read_option(:account_id)
|
126
165
|
|
127
|
-
if
|
128
|
-
|
166
|
+
response = if credential_exists
|
167
|
+
update_credential(server, account_id, params, type)
|
129
168
|
else
|
130
|
-
|
169
|
+
create_credential(server, account_id, params)
|
131
170
|
end
|
171
|
+
|
172
|
+
handle_result_for('GCR', response)
|
132
173
|
end
|
133
174
|
|
134
175
|
desc 'ghcr', 'Connect to GitHub Container Registry (ghcr.io)'
|
@@ -142,32 +183,37 @@ module Uffizzi
|
|
142
183
|
credential_exists = credential_exists?(type)
|
143
184
|
handle_existing_credential_options('ghcr') if credential_exists
|
144
185
|
|
145
|
-
username =
|
146
|
-
password = options[:token] || ENV['GITHUB_ACCESS_TOKEN'] || Uffizzi.ui.ask('Access Token:', echo: false)
|
186
|
+
username, password = Uffizzi::ConnectHelper.get_ghcr_data(options)
|
147
187
|
|
148
188
|
params = {
|
149
189
|
username: username,
|
150
190
|
password: password,
|
151
191
|
type: type,
|
152
192
|
}
|
153
|
-
|
154
193
|
server = ConfigFile.read_option(:server)
|
155
|
-
|
194
|
+
account_id = ConfigFile.read_option(:account_id)
|
156
195
|
|
157
|
-
if
|
158
|
-
|
196
|
+
response = if credential_exists
|
197
|
+
update_credential(server, account_id, params, type)
|
159
198
|
else
|
160
|
-
|
199
|
+
create_credential(server, account_id, params)
|
161
200
|
end
|
201
|
+
|
202
|
+
handle_result_for('GHCR', response)
|
162
203
|
end
|
163
204
|
|
164
205
|
map 'list-credentials' => 'list_credentials'
|
165
206
|
map 'docker-hub' => 'docker_hub'
|
207
|
+
map 'docker-registry' => 'docker_registry'
|
166
208
|
|
167
209
|
private
|
168
210
|
|
169
|
-
def
|
170
|
-
ResponseHelper.created?(response) || ResponseHelper.ok?(response)
|
211
|
+
def handle_result_for(credential_type, response)
|
212
|
+
if ResponseHelper.created?(response) || ResponseHelper.ok?(response)
|
213
|
+
print_success_message(credential_type)
|
214
|
+
else
|
215
|
+
ResponseHelper.handle_failed_response(response)
|
216
|
+
end
|
171
217
|
end
|
172
218
|
|
173
219
|
def prepare_registry_url(registry_url)
|
@@ -176,14 +222,21 @@ module Uffizzi
|
|
176
222
|
"https://#{registry_url}"
|
177
223
|
end
|
178
224
|
|
179
|
-
def print_success_message(
|
180
|
-
Uffizzi.ui.say("Successfully connected to #{
|
225
|
+
def print_success_message(credential_type)
|
226
|
+
Uffizzi.ui.say("Successfully connected to #{credential_type}.")
|
181
227
|
end
|
182
228
|
|
183
229
|
def credential_exists?(type)
|
184
230
|
server = ConfigFile.read_option(:server)
|
185
|
-
|
186
|
-
|
231
|
+
account_id = ConfigFile.read_option(:account_id)
|
232
|
+
response = check_credential(server, account_id, type)
|
233
|
+
return false if ResponseHelper.ok?(response)
|
234
|
+
return true if ResponseHelper.unprocessable_entity?(response)
|
235
|
+
|
236
|
+
if ResponseHelper.forbidden?(response)
|
237
|
+
Uffizzi.ui.say('Unauthorized. Skipping credentials action.')
|
238
|
+
exit(true)
|
239
|
+
end
|
187
240
|
end
|
188
241
|
|
189
242
|
def handle_existing_credential_options(credential_type_slug)
|
@@ -202,10 +255,6 @@ module Uffizzi
|
|
202
255
|
end
|
203
256
|
end
|
204
257
|
|
205
|
-
def create_or_update_credential(server, params, create: true)
|
206
|
-
create ? create_credential(server, params) : update_credential(server, params, params[:type])
|
207
|
-
end
|
208
|
-
|
209
258
|
def handle_list_credentials_success(response)
|
210
259
|
credentials = response[:body][:credentials]
|
211
260
|
credentials.each do |credential|
|
@@ -10,6 +10,8 @@ module Uffizzi
|
|
10
10
|
connection_type = case credential_type
|
11
11
|
when 'docker-hub'
|
12
12
|
Uffizzi.configuration.credential_types[:dockerhub]
|
13
|
+
when 'docker-registry'
|
14
|
+
Uffizzi.configuration.credential_types[:docker_registry]
|
13
15
|
when 'acr'
|
14
16
|
Uffizzi.configuration.credential_types[:azure]
|
15
17
|
when 'ecr'
|
@@ -22,10 +24,10 @@ module Uffizzi
|
|
22
24
|
raise Uffizzi::Error.new('Unsupported credential type.')
|
23
25
|
end
|
24
26
|
|
25
|
-
response = delete_credential(ConfigFile.read_option(:server), connection_type)
|
27
|
+
response = delete_credential(ConfigFile.read_option(:server), ConfigFile.read_option(:account_id), connection_type)
|
26
28
|
|
27
29
|
if ResponseHelper.no_content?(response)
|
28
|
-
Uffizzi.ui.say("Successfully disconnected #{connection_name(credential_type)}
|
30
|
+
Uffizzi.ui.say("Successfully disconnected from #{connection_name(credential_type)}.")
|
29
31
|
else
|
30
32
|
ResponseHelper.handle_failed_response(response)
|
31
33
|
end
|
@@ -36,6 +38,7 @@ module Uffizzi
|
|
36
38
|
def connection_name(credential_type)
|
37
39
|
{
|
38
40
|
'docker-hub' => 'DockerHub',
|
41
|
+
'docker-registry' => 'Docker Registry',
|
39
42
|
'acr' => 'ACR',
|
40
43
|
'ecr' => 'ECR',
|
41
44
|
'gcr' => 'GCR',
|
data/lib/uffizzi/cli/login.rb
CHANGED
@@ -34,17 +34,17 @@ module Uffizzi
|
|
34
34
|
|
35
35
|
def set_server
|
36
36
|
config_server = ConfigFile.exists? ? read_option_from_config(:server) : nil
|
37
|
-
server_address = @options[:server] || config_server || Uffizzi.ui.ask('Server: ')
|
37
|
+
server_address = (@options[:server] || config_server || Uffizzi.ui.ask('Server:')).sub(/\/+$/, '')
|
38
38
|
server_address.start_with?('http:', 'https:') ? server_address : "https://#{server_address}"
|
39
39
|
end
|
40
40
|
|
41
41
|
def set_username
|
42
42
|
config_username = ConfigFile.exists? ? read_option_from_config(:username) : nil
|
43
|
-
@options[:username] || config_username || Uffizzi.ui.ask('Username:
|
43
|
+
@options[:username] || config_username || Uffizzi.ui.ask('Username:')
|
44
44
|
end
|
45
45
|
|
46
46
|
def set_password
|
47
|
-
ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password:
|
47
|
+
ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password:', echo: false)
|
48
48
|
end
|
49
49
|
|
50
50
|
def read_option_from_config(option)
|
@@ -61,6 +61,7 @@ module Uffizzi
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def handle_succeed_response(response, server, username)
|
64
|
+
# TODO Choose a personal account
|
64
65
|
account = response[:body][:user][:accounts].first
|
65
66
|
return Uffizzi.ui.say('No account related to this email') unless account_valid?(account)
|
66
67
|
|
@@ -95,9 +96,11 @@ module Uffizzi
|
|
95
96
|
end
|
96
97
|
all_choices = choices + [{ name: 'Create a new project', value: nil }]
|
97
98
|
answer = Uffizzi.prompt.select(question, all_choices)
|
98
|
-
return
|
99
|
+
return create_new_project(server) unless answer
|
99
100
|
|
100
|
-
|
101
|
+
account_id = projects.detect { |project| project[:slug] == answer }[:account_id]
|
102
|
+
ConfigFile.write_option(:project, answer)
|
103
|
+
ConfigFile.write_option(:account_id, account_id)
|
101
104
|
end
|
102
105
|
|
103
106
|
def create_new_project(server)
|
@@ -116,7 +119,8 @@ module Uffizzi
|
|
116
119
|
},
|
117
120
|
}
|
118
121
|
|
119
|
-
|
122
|
+
account_id = ConfigFile.read_option(:account_id)
|
123
|
+
response = create_project(server, account_id, params)
|
120
124
|
|
121
125
|
if ResponseHelper.created?(response)
|
122
126
|
handle_create_project_succeess(response)
|
@@ -139,6 +143,7 @@ module Uffizzi
|
|
139
143
|
project = response[:body][:project]
|
140
144
|
|
141
145
|
ConfigFile.write_option(:project, project[:slug])
|
146
|
+
ConfigFile.write_option(:account_id, project[:account_id])
|
142
147
|
|
143
148
|
Uffizzi.ui.say("Project #{project[:name]} was successfully created")
|
144
149
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uffizzi'
|
4
|
+
require 'uffizzi/response_helper'
|
5
|
+
require 'uffizzi/clients/api/api_client'
|
6
|
+
|
7
|
+
module Uffizzi
|
8
|
+
class Cli::LoginByIdentityToken
|
9
|
+
include ApiClient
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
token = @options[:token]
|
17
|
+
server = @options[:server]
|
18
|
+
params = prepare_request_params(token)
|
19
|
+
response = create_ci_session(server, params)
|
20
|
+
|
21
|
+
if ResponseHelper.created?(response)
|
22
|
+
handle_succeed_response(response, server)
|
23
|
+
else
|
24
|
+
ResponseHelper.handle_failed_response(response)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def prepare_request_params(token)
|
31
|
+
{
|
32
|
+
user: {
|
33
|
+
token: token,
|
34
|
+
},
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle_succeed_response(response, server)
|
39
|
+
ConfigFile.write_option(:server, server)
|
40
|
+
ConfigFile.write_option(:cookie, response[:headers])
|
41
|
+
ConfigFile.write_option(:account_id, response[:body][:account_id])
|
42
|
+
ConfigFile.write_option(:project, response[:body][:project_slug])
|
43
|
+
|
44
|
+
Uffizzi.ui.say('Successful Login by Identity Token')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/uffizzi/cli/preview.rb
CHANGED
@@ -12,19 +12,24 @@ module Uffizzi
|
|
12
12
|
desc 'service', 'Show the preview services info'
|
13
13
|
require_relative 'preview/service'
|
14
14
|
subcommand 'service', Uffizzi::Cli::Preview::Service
|
15
|
+
|
15
16
|
desc 'list', 'List all previews'
|
17
|
+
method_option :filter, required: false, type: :string, aliases: '-f'
|
18
|
+
method_option :output, required: false, type: :string, aliases: '-o', enum: ['json']
|
16
19
|
def list
|
17
20
|
run('list')
|
18
21
|
end
|
19
22
|
|
20
23
|
desc 'create [COMPOSE_FILE]', 'Create a preview'
|
21
24
|
method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
|
25
|
+
method_option :"set-labels", required: false, type: :string, aliases: '-s'
|
22
26
|
def create(file_path = nil)
|
23
27
|
run('create', file_path: file_path)
|
24
28
|
end
|
25
29
|
|
26
30
|
desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a preview'
|
27
31
|
method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
|
32
|
+
method_option :"set-labels", required: false, type: :string, aliases: '-s'
|
28
33
|
def update(deployment_name, file_path)
|
29
34
|
run('update', deployment_name: deployment_name, file_path: file_path)
|
30
35
|
end
|
@@ -47,10 +52,7 @@ module Uffizzi
|
|
47
52
|
private
|
48
53
|
|
49
54
|
def run(command, file_path: nil, deployment_name: nil)
|
50
|
-
|
51
|
-
Uffizzi.ui.output_format = options[:output]
|
52
|
-
Uffizzi.ui.disable_stdout
|
53
|
-
end
|
55
|
+
Uffizzi.ui.output_format = options[:output]
|
54
56
|
raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
|
55
57
|
raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
|
56
58
|
|
@@ -58,11 +60,11 @@ module Uffizzi
|
|
58
60
|
|
59
61
|
case command
|
60
62
|
when 'list'
|
61
|
-
handle_list_command(project_slug)
|
63
|
+
handle_list_command(project_slug, options[:filter])
|
62
64
|
when 'create'
|
63
|
-
handle_create_command(file_path, project_slug)
|
65
|
+
handle_create_command(file_path, project_slug, options[:"set-labels"])
|
64
66
|
when 'update'
|
65
|
-
handle_update_command(deployment_name, file_path, project_slug)
|
67
|
+
handle_update_command(deployment_name, file_path, project_slug, options[:"set-labels"])
|
66
68
|
when 'delete'
|
67
69
|
handle_delete_command(deployment_name, project_slug)
|
68
70
|
when 'describe'
|
@@ -72,8 +74,9 @@ module Uffizzi
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
def handle_list_command(project_slug)
|
76
|
-
|
77
|
+
def handle_list_command(project_slug, filter)
|
78
|
+
parsed_filter = filter.nil? ? {} : build_filter_params(filter)
|
79
|
+
response = fetch_deployments(ConfigFile.read_option(:server), project_slug, parsed_filter)
|
77
80
|
|
78
81
|
if ResponseHelper.ok?(response)
|
79
82
|
handle_succeed_list_response(response)
|
@@ -82,8 +85,10 @@ module Uffizzi
|
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
85
|
-
def handle_create_command(file_path, project_slug)
|
86
|
-
|
88
|
+
def handle_create_command(file_path, project_slug, labels)
|
89
|
+
Uffizzi.ui.disable_stdout unless options[:output].nil?
|
90
|
+
params = prepare_params(file_path, labels)
|
91
|
+
|
87
92
|
response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
|
88
93
|
|
89
94
|
if !ResponseHelper.created?(response)
|
@@ -101,12 +106,13 @@ module Uffizzi
|
|
101
106
|
handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
|
102
107
|
end
|
103
108
|
|
104
|
-
def handle_update_command(deployment_name, file_path, project_slug)
|
109
|
+
def handle_update_command(deployment_name, file_path, project_slug, labels)
|
110
|
+
Uffizzi.ui.disable_stdout unless options[:output].nil?
|
105
111
|
deployment_id = PreviewService.read_deployment_id(deployment_name)
|
106
112
|
|
107
113
|
raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
|
108
114
|
|
109
|
-
params = prepare_params(file_path)
|
115
|
+
params = prepare_params(file_path, labels)
|
110
116
|
response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
|
111
117
|
|
112
118
|
if !ResponseHelper.ok?(response)
|
@@ -175,7 +181,11 @@ module Uffizzi
|
|
175
181
|
raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
|
176
182
|
|
177
183
|
deployments.each do |deployment|
|
178
|
-
Uffizzi.ui.
|
184
|
+
if Uffizzi.ui.output_format.nil?
|
185
|
+
Uffizzi.ui.say("deployment-#{deployment[:id]}")
|
186
|
+
else
|
187
|
+
Uffizzi.ui.pretty_say(deployment)
|
188
|
+
end
|
179
189
|
end
|
180
190
|
end
|
181
191
|
|
@@ -205,26 +215,10 @@ module Uffizzi
|
|
205
215
|
end
|
206
216
|
end
|
207
217
|
|
208
|
-
def prepare_params(file_path)
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
raise Uffizzi::Error.new(e.message)
|
213
|
-
end
|
214
|
-
|
215
|
-
compose_file_dir = File.dirname(file_path)
|
216
|
-
dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
|
217
|
-
absolute_path = File.absolute_path(file_path)
|
218
|
-
compose_file_params = {
|
219
|
-
path: absolute_path,
|
220
|
-
content: Base64.encode64(compose_file_data),
|
221
|
-
source: absolute_path,
|
222
|
-
}
|
223
|
-
|
224
|
-
{
|
225
|
-
compose_file: compose_file_params,
|
226
|
-
dependencies: dependencies,
|
227
|
-
}
|
218
|
+
def prepare_params(file_path, labels)
|
219
|
+
compose_file_params = file_path.nil? ? {} : build_compose_file_params(file_path)
|
220
|
+
metadata_params = labels.nil? ? {} : build_metadata_params(labels)
|
221
|
+
compose_file_params.merge(metadata_params)
|
228
222
|
end
|
229
223
|
|
230
224
|
def handle_preview_interruption(deployment_id, server, project_slug)
|
@@ -251,10 +245,77 @@ module Uffizzi
|
|
251
245
|
end
|
252
246
|
|
253
247
|
def build_deployment_data(deployment)
|
248
|
+
url_server = ConfigFile.read_option(:server)
|
249
|
+
|
254
250
|
{
|
255
251
|
id: "deployment-#{deployment[:id]}",
|
256
252
|
url: "https://#{deployment[:preview_url]}",
|
253
|
+
containers_uri: "#{url_server}/projects/#{deployment[:project_id]}/deployments/#{deployment[:id]}/containers",
|
257
254
|
}
|
258
255
|
end
|
256
|
+
|
257
|
+
def build_compose_file_params(file_path)
|
258
|
+
begin
|
259
|
+
compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
|
260
|
+
rescue Errno::ENOENT => e
|
261
|
+
raise Uffizzi::Error.new(e.message)
|
262
|
+
end
|
263
|
+
|
264
|
+
compose_file_dir = File.dirname(file_path)
|
265
|
+
dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
|
266
|
+
absolute_path = File.absolute_path(file_path)
|
267
|
+
compose_file_params = {
|
268
|
+
path: absolute_path,
|
269
|
+
content: Base64.encode64(compose_file_data),
|
270
|
+
source: absolute_path,
|
271
|
+
}
|
272
|
+
|
273
|
+
{
|
274
|
+
compose_file: compose_file_params,
|
275
|
+
dependencies: dependencies,
|
276
|
+
}
|
277
|
+
end
|
278
|
+
|
279
|
+
def build_metadata_params(labels)
|
280
|
+
{
|
281
|
+
metadata: {
|
282
|
+
'labels' => parse_params(labels, 'Labels'),
|
283
|
+
},
|
284
|
+
}
|
285
|
+
end
|
286
|
+
|
287
|
+
def build_filter_params(filter_params)
|
288
|
+
{
|
289
|
+
'labels' => parse_params(filter_params, 'Filtering parameters'),
|
290
|
+
}
|
291
|
+
end
|
292
|
+
|
293
|
+
def parse_params(params, params_type)
|
294
|
+
validate_params(params, params_type)
|
295
|
+
params.split(' ').reduce({}) do |acc, param|
|
296
|
+
stringified_keys, value = param.split('=', 2)
|
297
|
+
keys = stringified_keys.split('.', -1)
|
298
|
+
inner_pair = { keys.pop => value }
|
299
|
+
prepared_param = keys.reverse.reduce(inner_pair) { |res, key| { key => res } }
|
300
|
+
merge_params(acc, prepared_param)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def validate_params(params, params_type)
|
305
|
+
params.split(' ').each do |param|
|
306
|
+
stringified_keys, value = param.split('=', 2)
|
307
|
+
raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if value.nil? || stringified_keys.nil? || value.empty?
|
308
|
+
|
309
|
+
keys = stringified_keys.split('.', -1)
|
310
|
+
raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if keys.empty? || keys.any?(&:empty?)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def merge_params(result, param)
|
315
|
+
key = param.keys.first
|
316
|
+
return result.merge(param) unless result.has_key?(key)
|
317
|
+
|
318
|
+
{ key => result[key].merge(merge_params(result[key], param[key])) }
|
319
|
+
end
|
259
320
|
end
|
260
321
|
end
|
data/lib/uffizzi/cli/project.rb
CHANGED
@@ -102,12 +102,13 @@ module Uffizzi
|
|
102
102
|
raise Uffizzi::Error.new('Slug must not content spaces or special characters') unless slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)
|
103
103
|
|
104
104
|
server = ConfigFile.read_option(:server)
|
105
|
+
account_id = ConfigFile.read_option(:account_id)
|
105
106
|
params = {
|
106
107
|
name: name,
|
107
108
|
description: options[:description],
|
108
109
|
slug: slug,
|
109
110
|
}
|
110
|
-
response = create_project(server, params)
|
111
|
+
response = create_project(server, account_id, params)
|
111
112
|
|
112
113
|
if ResponseHelper.created?(response)
|
113
114
|
handle_create_success_response(response)
|
@@ -165,6 +166,7 @@ module Uffizzi
|
|
165
166
|
|
166
167
|
def set_default_project(project)
|
167
168
|
ConfigFile.write_option(:project, project[:slug])
|
169
|
+
ConfigFile.write_option(:account_id, project[:account_id])
|
168
170
|
end
|
169
171
|
end
|
170
172
|
end
|