uffizzi-cli 0.11.4 → 0.14.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 +109 -49
- data/lib/uffizzi/cli/disconnect.rb +4 -1
- data/lib/uffizzi/cli/login.rb +3 -3
- data/lib/uffizzi/cli/preview.rb +95 -34
- data/lib/uffizzi/clients/api/api_client.rb +10 -3
- data/lib/uffizzi/clients/api/api_routes.rb +5 -3
- data/lib/uffizzi/clients/api/http_client.rb +4 -4
- data/lib/uffizzi/helpers/connect_helper.rb +45 -0
- data/lib/uffizzi/version.rb +1 -1
- data/man/uffizzi-connect +31 -26
- 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 +32 -18
- 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 +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7a27f279e964f07491f920557722194d65c8a9259487a5a717707f6075d164b
|
4
|
+
data.tar.gz: d9825fe3425b0dde3dbe1e4528686100c6ca22f30aed4aa7a332cf991bbb6480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 179a75d66bd89efc1ad9b3decf5ebc6c5526b2fe0fdd02e616940b4f12544505c956874a0649a99a2c5d1e14fce6e1dcda305a9028e08d8e9c2b8b5f63955fb5
|
7
|
+
data.tar.gz: a8d2637bef4250c33bb1cc8725556a2758384c9115938865e8acd70b92fce515ccd94b691913341c6b6f64a29f6d9ff34e99148fd62cacf8d6551d72a1222508
|
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
|
@@ -20,39 +21,76 @@ module Uffizzi
|
|
20
21
|
desc 'docker-hub', 'Connect to Docker Hub (hub.docker.com)'
|
21
22
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
22
23
|
desc: 'Skip raising an error within check the credential'
|
24
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
25
|
+
method_option :username, type: :string, aliases: :u
|
26
|
+
method_option :password, type: :string, aliases: :p
|
23
27
|
def docker_hub
|
24
28
|
type = Uffizzi.configuration.credential_types[:dockerhub]
|
25
|
-
|
29
|
+
credential_exists = credential_exists?(type)
|
30
|
+
handle_existing_credential_options('docker-hub') if credential_exists
|
26
31
|
|
27
|
-
username =
|
28
|
-
password = ENV['DOCKERHUB_PASSWORD'] || Uffizzi.ui.ask('Password: ', echo: false)
|
32
|
+
username, password = Uffizzi::ConnectHelper.get_docker_hub_data(options)
|
29
33
|
|
30
34
|
params = {
|
31
35
|
username: username,
|
32
36
|
password: password,
|
33
|
-
type:
|
37
|
+
type: type,
|
34
38
|
}
|
39
|
+
server = ConfigFile.read_option(:server)
|
40
|
+
|
41
|
+
response = if credential_exists
|
42
|
+
update_credential(server, params, type)
|
43
|
+
else
|
44
|
+
create_credential(server, params)
|
45
|
+
end
|
35
46
|
|
47
|
+
handle_result_for('Docker Hub', response)
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'docker-registry', 'Connect to any registry implementing the Docker Registry HTTP API protocol'
|
51
|
+
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
52
|
+
desc: 'Skip raising an error within check the credential'
|
53
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
54
|
+
method_option :registry, type: :string, aliases: :r
|
55
|
+
method_option :username, type: :string, aliases: :u
|
56
|
+
method_option :password, type: :string, aliases: :p
|
57
|
+
def docker_registry
|
58
|
+
type = Uffizzi.configuration.credential_types[:docker_registry]
|
59
|
+
credential_exists = credential_exists?(type)
|
60
|
+
handle_existing_credential_options('docker-registry') if credential_exists
|
61
|
+
|
62
|
+
registry_url, username, password = Uffizzi::ConnectHelper.get_docker_registry_data(options)
|
63
|
+
|
64
|
+
params = {
|
65
|
+
registry_url: prepare_registry_url(registry_url),
|
66
|
+
username: username,
|
67
|
+
password: password,
|
68
|
+
type: type,
|
69
|
+
}
|
36
70
|
server = ConfigFile.read_option(:server)
|
37
|
-
response = create_credential(server, params)
|
38
71
|
|
39
|
-
if
|
40
|
-
|
72
|
+
response = if credential_exists
|
73
|
+
update_credential(server, params, type)
|
41
74
|
else
|
42
|
-
|
75
|
+
create_credential(server, params)
|
43
76
|
end
|
77
|
+
|
78
|
+
handle_result_for('Docker Registry', response)
|
44
79
|
end
|
45
80
|
|
46
81
|
desc 'acr', 'Connect to Azure Container Registry (azurecr.io)'
|
47
82
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
48
83
|
desc: 'Skip raising an error within check the credential'
|
84
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
85
|
+
method_option :registry, type: :string, aliases: :r
|
86
|
+
method_option :username, type: :string, aliases: :u
|
87
|
+
method_option :password, type: :string, aliases: :p
|
49
88
|
def acr
|
50
89
|
type = Uffizzi.configuration.credential_types[:azure]
|
51
|
-
|
90
|
+
credential_exists = credential_exists?(type)
|
91
|
+
handle_existing_credential_options('acr') if credential_exists
|
52
92
|
|
53
|
-
registry_url
|
54
|
-
username = ENV['ACR_USERNAME'] || Uffizzi.ui.ask('Docker ID: ')
|
55
|
-
password = ENV['ACR_PASSWORD'] || Uffizzi.ui.ask('Password/Access Token: ', echo: false)
|
93
|
+
registry_url, username, password = Uffizzi::ConnectHelper.get_acr_data(options)
|
56
94
|
|
57
95
|
params = {
|
58
96
|
username: username,
|
@@ -60,51 +98,56 @@ module Uffizzi
|
|
60
98
|
registry_url: prepare_registry_url(registry_url),
|
61
99
|
type: type,
|
62
100
|
}
|
63
|
-
|
64
101
|
server = ConfigFile.read_option(:server)
|
65
|
-
response = create_credential(server, params)
|
66
102
|
|
67
|
-
if
|
68
|
-
|
103
|
+
response = if credential_exists
|
104
|
+
update_credential(server, params, type)
|
69
105
|
else
|
70
|
-
|
106
|
+
create_credential(server, params)
|
71
107
|
end
|
108
|
+
|
109
|
+
handle_result_for('ACR', response)
|
72
110
|
end
|
73
111
|
|
74
112
|
desc 'ecr', 'Connect to Amazon Elastic Container Registry'
|
75
113
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
76
114
|
desc: 'Skip raising an error within check the credential'
|
115
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
116
|
+
method_option :registry, type: :string, aliases: :r
|
117
|
+
method_option :id, type: :string
|
118
|
+
method_option :secret, type: :string, aliases: :s
|
77
119
|
def ecr
|
78
120
|
type = Uffizzi.configuration.credential_types[:amazon]
|
79
|
-
|
121
|
+
credential_exists = credential_exists?(type)
|
122
|
+
handle_existing_credential_options('ecr') if credential_exists
|
80
123
|
|
81
|
-
registry_url
|
82
|
-
access_key = ENV['AWS_ACCESS_KEY_ID'] || Uffizzi.ui.ask('Access key ID: ')
|
83
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || Uffizzi.ui.ask('Secret access key: ', echo: false)
|
124
|
+
registry_url, access_key_id, secret_access_key = Uffizzi::ConnectHelper.get_ecr_data(options)
|
84
125
|
|
85
126
|
params = {
|
86
|
-
username:
|
127
|
+
username: access_key_id,
|
87
128
|
password: secret_access_key,
|
88
129
|
registry_url: prepare_registry_url(registry_url),
|
89
130
|
type: type,
|
90
131
|
}
|
91
|
-
|
92
132
|
server = ConfigFile.read_option(:server)
|
93
|
-
response = create_credential(server, params)
|
94
133
|
|
95
|
-
if
|
96
|
-
|
134
|
+
response = if credential_exists
|
135
|
+
update_credential(server, params, type)
|
97
136
|
else
|
98
|
-
|
137
|
+
create_credential(server, params)
|
99
138
|
end
|
139
|
+
|
140
|
+
handle_result_for('ECR', response)
|
100
141
|
end
|
101
142
|
|
102
143
|
desc 'gcr', 'Connect to Google Container Registry (gcr.io)'
|
103
144
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
104
145
|
desc: 'Skip raising an error within check the credential'
|
146
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
105
147
|
def gcr(credential_file_path = nil)
|
106
148
|
type = Uffizzi.configuration.credential_types[:google]
|
107
|
-
|
149
|
+
credential_exists = credential_exists?(type)
|
150
|
+
handle_existing_credential_options('gcr') if credential_exists
|
108
151
|
|
109
152
|
credential_content = google_service_account_content(credential_file_path)
|
110
153
|
|
@@ -112,71 +155,88 @@ module Uffizzi
|
|
112
155
|
password: credential_content,
|
113
156
|
type: type,
|
114
157
|
}
|
115
|
-
|
116
158
|
server = ConfigFile.read_option(:server)
|
117
|
-
response = create_credential(server, params)
|
118
159
|
|
119
|
-
if
|
120
|
-
|
160
|
+
response = if credential_exists
|
161
|
+
update_credential(server, params, type)
|
121
162
|
else
|
122
|
-
|
163
|
+
create_credential(server, params)
|
123
164
|
end
|
165
|
+
|
166
|
+
handle_result_for('GCR', response)
|
124
167
|
end
|
125
168
|
|
126
169
|
desc 'ghcr', 'Connect to GitHub Container Registry (ghcr.io)'
|
127
170
|
method_option :skip_raise_existence_error, type: :boolean, default: false,
|
128
171
|
desc: 'Skip raising an error within check the credential'
|
172
|
+
method_option :update_credential_if_exists, type: :boolean, default: false
|
129
173
|
method_option :username, type: :string, aliases: :u
|
130
174
|
method_option :token, type: :string, aliases: :t
|
131
175
|
def ghcr
|
132
176
|
type = Uffizzi.configuration.credential_types[:github_registry]
|
133
|
-
|
177
|
+
credential_exists = credential_exists?(type)
|
178
|
+
handle_existing_credential_options('ghcr') if credential_exists
|
134
179
|
|
135
|
-
username =
|
136
|
-
password = options[:token] || ENV['GITHUB_ACCESS_TOKEN'] || Uffizzi.ui.ask('Access Token:', echo: false)
|
180
|
+
username, password = Uffizzi::ConnectHelper.get_ghcr_data(options)
|
137
181
|
|
138
182
|
params = {
|
139
183
|
username: username,
|
140
184
|
password: password,
|
141
185
|
type: type,
|
142
186
|
}
|
143
|
-
|
144
187
|
server = ConfigFile.read_option(:server)
|
145
|
-
response = create_credential(server, params)
|
146
188
|
|
147
|
-
if
|
148
|
-
|
189
|
+
response = if credential_exists
|
190
|
+
update_credential(server, params, type)
|
149
191
|
else
|
150
|
-
|
192
|
+
create_credential(server, params)
|
151
193
|
end
|
194
|
+
|
195
|
+
handle_result_for('GHCR', response)
|
152
196
|
end
|
153
197
|
|
154
198
|
map 'list-credentials' => 'list_credentials'
|
155
199
|
map 'docker-hub' => 'docker_hub'
|
200
|
+
map 'docker-registry' => 'docker_registry'
|
156
201
|
|
157
202
|
private
|
158
203
|
|
204
|
+
def handle_result_for(credential_type, response)
|
205
|
+
if ResponseHelper.created?(response) || ResponseHelper.ok?(response)
|
206
|
+
print_success_message(credential_type)
|
207
|
+
else
|
208
|
+
ResponseHelper.handle_failed_response(response)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
159
212
|
def prepare_registry_url(registry_url)
|
160
213
|
return registry_url if registry_url.match?(/^(?:http(s)?:\/\/)/)
|
161
214
|
|
162
215
|
"https://#{registry_url}"
|
163
216
|
end
|
164
217
|
|
165
|
-
def print_success_message(
|
166
|
-
Uffizzi.ui.say("Successfully connected to #{
|
218
|
+
def print_success_message(credential_type)
|
219
|
+
Uffizzi.ui.say("Successfully connected to #{credential_type}.")
|
167
220
|
end
|
168
221
|
|
169
|
-
def
|
222
|
+
def credential_exists?(type)
|
170
223
|
server = ConfigFile.read_option(:server)
|
171
224
|
response = check_credential(server, type)
|
172
|
-
|
225
|
+
!ResponseHelper.ok?(response)
|
226
|
+
end
|
227
|
+
|
228
|
+
def handle_existing_credential_options(credential_type_slug)
|
229
|
+
if options.update_credential_if_exists?
|
230
|
+
Uffizzi.ui.say('Updating existing credential.')
|
231
|
+
return
|
232
|
+
end
|
173
233
|
|
174
234
|
if options.skip_raise_existence_error?
|
175
|
-
Uffizzi.ui.say("
|
235
|
+
Uffizzi.ui.say("Credential of type #{credential_type_slug} already exists for this account.")
|
176
236
|
exit(true)
|
177
237
|
else
|
178
|
-
message = "
|
179
|
-
"To remove them, run
|
238
|
+
message = "Credential of type #{credential_type_slug} already exists for this account.\n" \
|
239
|
+
"To remove them, run uffizzi disconnect #{credential_type_slug}."
|
180
240
|
raise Uffizzi::Error.new(message)
|
181
241
|
end
|
182
242
|
end
|
@@ -204,7 +264,7 @@ module Uffizzi
|
|
204
264
|
def google_service_account_content(credential_file_path = nil)
|
205
265
|
return ENV['GCLOUD_SERVICE_KEY'] if ENV['GCLOUD_SERVICE_KEY']
|
206
266
|
|
207
|
-
|
267
|
+
raise Uffizzi::Error.new("Path to a google service account key file wasn't specified.") if credential_file_path.nil?
|
208
268
|
|
209
269
|
begin
|
210
270
|
credential_content = File.read(credential_file_path)
|
@@ -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'
|
@@ -25,7 +27,7 @@ module Uffizzi
|
|
25
27
|
response = delete_credential(ConfigFile.read_option(:server), 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)
|
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
|
@@ -70,6 +70,13 @@ module ApiClient
|
|
70
70
|
build_response(response)
|
71
71
|
end
|
72
72
|
|
73
|
+
def update_credential(server, params, type)
|
74
|
+
uri = credential_uri(server, type)
|
75
|
+
response = http_client.make_put_request(uri, params)
|
76
|
+
|
77
|
+
build_response(response)
|
78
|
+
end
|
79
|
+
|
73
80
|
def fetch_deployment_services(server, project_slug, deployment_id)
|
74
81
|
uri = preview_services_uri(server, project_slug, deployment_id)
|
75
82
|
response = http_client.make_get_request(uri)
|
@@ -78,7 +85,7 @@ module ApiClient
|
|
78
85
|
end
|
79
86
|
|
80
87
|
def delete_credential(server, credential_type)
|
81
|
-
uri =
|
88
|
+
uri = credential_uri(server, credential_type)
|
82
89
|
response = http_client.make_delete_request(uri)
|
83
90
|
|
84
91
|
build_response(response)
|
@@ -140,8 +147,8 @@ module ApiClient
|
|
140
147
|
build_response(response)
|
141
148
|
end
|
142
149
|
|
143
|
-
def fetch_deployments(server, project_slug)
|
144
|
-
uri = deployments_uri(server, project_slug)
|
150
|
+
def fetch_deployments(server, project_slug, filter)
|
151
|
+
uri = deployments_uri(server, project_slug, filter)
|
145
152
|
response = http_client.make_get_request(uri)
|
146
153
|
|
147
154
|
build_response(response)
|
@@ -32,8 +32,10 @@ module ApiRoutes
|
|
32
32
|
"#{compose_files_uri(server, project_slug)}/validate"
|
33
33
|
end
|
34
34
|
|
35
|
-
def deployments_uri(server, project_slug)
|
36
|
-
"#{server}/api/cli/v1/projects/#{project_slug}/deployments"
|
35
|
+
def deployments_uri(server, project_slug, filter = nil)
|
36
|
+
return "#{server}/api/cli/v1/projects/#{project_slug}/deployments" if filter.nil?
|
37
|
+
|
38
|
+
"#{server}/api/cli/v1/projects/#{project_slug}/deployments?q=#{filter.to_json}"
|
37
39
|
end
|
38
40
|
|
39
41
|
def deployment_uri(server, project_slug, deployment_id)
|
@@ -64,7 +66,7 @@ module ApiRoutes
|
|
64
66
|
"#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers"
|
65
67
|
end
|
66
68
|
|
67
|
-
def
|
69
|
+
def credential_uri(server, credential_type)
|
68
70
|
"#{server}/api/cli/v1/account/credentials/#{credential_type}"
|
69
71
|
end
|
70
72
|
|
@@ -50,13 +50,13 @@ module Uffizzi
|
|
50
50
|
headers = { 'Content-Type' => 'application/json' }
|
51
51
|
request = case method
|
52
52
|
when :get
|
53
|
-
Net::HTTP::Get.new(uri.
|
53
|
+
Net::HTTP::Get.new(uri.request_uri, headers)
|
54
54
|
when :post
|
55
|
-
Net::HTTP::Post.new(uri.
|
55
|
+
Net::HTTP::Post.new(uri.request_uri, headers)
|
56
56
|
when :delete
|
57
|
-
Net::HTTP::Delete.new(uri.
|
57
|
+
Net::HTTP::Delete.new(uri.request_uri, headers)
|
58
58
|
when :put
|
59
|
-
Net::HTTP::Put.new(uri.
|
59
|
+
Net::HTTP::Put.new(uri.request_uri, headers)
|
60
60
|
end
|
61
61
|
if request.instance_of?(Net::HTTP::Post) || request.instance_of?(Net::HTTP::Put)
|
62
62
|
request.body = params.to_json
|