uffizzi-cli 0.11.5 → 1.0.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/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
|