uffizzi-cli 0.12.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/uffizzi/cli/connect.rb +29 -15
- data/lib/uffizzi/cli/disconnect.rb +1 -1
- 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 +102 -40
- 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/services/project_service.rb +1 -0
- data/lib/uffizzi/shell.rb +24 -15
- data/lib/uffizzi/version.rb +1 -1
- 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 +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88f0a01cdfea0ed8e8d4ad54d776f517f84d74c424f2db15569fb788e7fe3868
|
4
|
+
data.tar.gz: e690fe7b2552ae4215687aac32420cb4b39e3cd2dd4b1d4fcf723538e49b213c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77198a935bf13d106bd191e017094ecc431cc09e307608a4f23ccd3bbd5591b7d12def5f4c3eff77f0389acfe6384f2a80ad63389d7ce8b7f51b9768d8bd0d09
|
7
|
+
data.tar.gz: c945bf73973d7a55fae9e3cf9502a1cfacafc65671b292913333c61f644fe0ca9c5402e7ae7ce54ae88bd08de117e016614d72e9474634ff725581828ea288bb
|
data/lib/uffizzi/cli/connect.rb
CHANGED
@@ -10,7 +10,8 @@ module Uffizzi
|
|
10
10
|
desc 'list-credentials', 'List existing credentials for an account'
|
11
11
|
def list_credentials
|
12
12
|
server = ConfigFile.read_option(:server)
|
13
|
-
|
13
|
+
account_id = ConfigFile.read_option(:account_id)
|
14
|
+
response = fetch_credentials(server, account_id)
|
14
15
|
if ResponseHelper.ok?(response)
|
15
16
|
handle_list_credentials_success(response)
|
16
17
|
else
|
@@ -37,11 +38,12 @@ module Uffizzi
|
|
37
38
|
type: type,
|
38
39
|
}
|
39
40
|
server = ConfigFile.read_option(:server)
|
41
|
+
account_id = ConfigFile.read_option(:account_id)
|
40
42
|
|
41
43
|
response = if credential_exists
|
42
|
-
update_credential(server, params, type)
|
44
|
+
update_credential(server, account_id, params, type)
|
43
45
|
else
|
44
|
-
create_credential(server, params)
|
46
|
+
create_credential(server, account_id, params)
|
45
47
|
end
|
46
48
|
|
47
49
|
handle_result_for('Docker Hub', response)
|
@@ -68,11 +70,12 @@ module Uffizzi
|
|
68
70
|
type: type,
|
69
71
|
}
|
70
72
|
server = ConfigFile.read_option(:server)
|
73
|
+
account_id = ConfigFile.read_option(:account_id)
|
71
74
|
|
72
75
|
response = if credential_exists
|
73
|
-
update_credential(server, params, type)
|
76
|
+
update_credential(server, account_id, params, type)
|
74
77
|
else
|
75
|
-
create_credential(server, params)
|
78
|
+
create_credential(server, account_id, params)
|
76
79
|
end
|
77
80
|
|
78
81
|
handle_result_for('Docker Registry', response)
|
@@ -99,11 +102,12 @@ module Uffizzi
|
|
99
102
|
type: type,
|
100
103
|
}
|
101
104
|
server = ConfigFile.read_option(:server)
|
105
|
+
account_id = ConfigFile.read_option(:account_id)
|
102
106
|
|
103
107
|
response = if credential_exists
|
104
|
-
update_credential(server, params, type)
|
108
|
+
update_credential(server, account_id, params, type)
|
105
109
|
else
|
106
|
-
create_credential(server, params)
|
110
|
+
create_credential(server, account_id, params)
|
107
111
|
end
|
108
112
|
|
109
113
|
handle_result_for('ACR', response)
|
@@ -130,11 +134,12 @@ module Uffizzi
|
|
130
134
|
type: type,
|
131
135
|
}
|
132
136
|
server = ConfigFile.read_option(:server)
|
137
|
+
account_id = ConfigFile.read_option(:account_id)
|
133
138
|
|
134
139
|
response = if credential_exists
|
135
|
-
update_credential(server, params, type)
|
140
|
+
update_credential(server, account_id, params, type)
|
136
141
|
else
|
137
|
-
create_credential(server, params)
|
142
|
+
create_credential(server, account_id, params)
|
138
143
|
end
|
139
144
|
|
140
145
|
handle_result_for('ECR', response)
|
@@ -156,11 +161,12 @@ module Uffizzi
|
|
156
161
|
type: type,
|
157
162
|
}
|
158
163
|
server = ConfigFile.read_option(:server)
|
164
|
+
account_id = ConfigFile.read_option(:account_id)
|
159
165
|
|
160
166
|
response = if credential_exists
|
161
|
-
update_credential(server, params, type)
|
167
|
+
update_credential(server, account_id, params, type)
|
162
168
|
else
|
163
|
-
create_credential(server, params)
|
169
|
+
create_credential(server, account_id, params)
|
164
170
|
end
|
165
171
|
|
166
172
|
handle_result_for('GCR', response)
|
@@ -185,11 +191,12 @@ module Uffizzi
|
|
185
191
|
type: type,
|
186
192
|
}
|
187
193
|
server = ConfigFile.read_option(:server)
|
194
|
+
account_id = ConfigFile.read_option(:account_id)
|
188
195
|
|
189
196
|
response = if credential_exists
|
190
|
-
update_credential(server, params, type)
|
197
|
+
update_credential(server, account_id, params, type)
|
191
198
|
else
|
192
|
-
create_credential(server, params)
|
199
|
+
create_credential(server, account_id, params)
|
193
200
|
end
|
194
201
|
|
195
202
|
handle_result_for('GHCR', response)
|
@@ -221,8 +228,15 @@ module Uffizzi
|
|
221
228
|
|
222
229
|
def credential_exists?(type)
|
223
230
|
server = ConfigFile.read_option(:server)
|
224
|
-
|
225
|
-
|
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
|
226
240
|
end
|
227
241
|
|
228
242
|
def handle_existing_credential_options(credential_type_slug)
|
@@ -24,7 +24,7 @@ module Uffizzi
|
|
24
24
|
raise Uffizzi::Error.new('Unsupported credential type.')
|
25
25
|
end
|
26
26
|
|
27
|
-
response = delete_credential(ConfigFile.read_option(:server), connection_type)
|
27
|
+
response = delete_credential(ConfigFile.read_option(:server), ConfigFile.read_option(:account_id), connection_type)
|
28
28
|
|
29
29
|
if ResponseHelper.no_content?(response)
|
30
30
|
Uffizzi.ui.say("Successfully disconnected from #{connection_name(credential_type)}.")
|
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', 'pretty-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,11 @@ 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
|
+
|
91
|
+
params = prepare_params(file_path, labels)
|
92
|
+
|
87
93
|
response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
|
88
94
|
|
89
95
|
if !ResponseHelper.created?(response)
|
@@ -101,12 +107,13 @@ module Uffizzi
|
|
101
107
|
handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
|
102
108
|
end
|
103
109
|
|
104
|
-
def handle_update_command(deployment_name, file_path, project_slug)
|
110
|
+
def handle_update_command(deployment_name, file_path, project_slug, labels)
|
111
|
+
Uffizzi.ui.disable_stdout unless options[:output].nil?
|
105
112
|
deployment_id = PreviewService.read_deployment_id(deployment_name)
|
106
113
|
|
107
114
|
raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
|
108
115
|
|
109
|
-
params = prepare_params(file_path)
|
116
|
+
params = prepare_params(file_path, labels)
|
110
117
|
response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
|
111
118
|
|
112
119
|
if !ResponseHelper.ok?(response)
|
@@ -139,7 +146,8 @@ module Uffizzi
|
|
139
146
|
end
|
140
147
|
|
141
148
|
def handle_succeed_events_response(response)
|
142
|
-
Uffizzi.ui.
|
149
|
+
Uffizzi.ui.output_format = Uffizzi::UI::Shell::PRETTY_JSON
|
150
|
+
Uffizzi.ui.say(response[:body][:events])
|
143
151
|
end
|
144
152
|
|
145
153
|
def handle_delete_command(deployment_name, project_slug)
|
@@ -174,9 +182,12 @@ module Uffizzi
|
|
174
182
|
deployments = response[:body][:deployments] || []
|
175
183
|
raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
|
176
184
|
|
177
|
-
|
178
|
-
|
185
|
+
if Uffizzi.ui.output_format.nil?
|
186
|
+
deployments = deployments.reduce('') do |acc, deployment|
|
187
|
+
"#{acc}deployment-#{deployment[:id]}\n"
|
188
|
+
end.strip
|
179
189
|
end
|
190
|
+
Uffizzi.ui.say(deployments)
|
180
191
|
end
|
181
192
|
|
182
193
|
def handle_succeed_delete_response(deployment_id)
|
@@ -192,9 +203,8 @@ module Uffizzi
|
|
192
203
|
|
193
204
|
container
|
194
205
|
end
|
195
|
-
deployment.
|
196
|
-
|
197
|
-
end
|
206
|
+
deployment_data = deployment.reduce('') { |acc, (key, value)| "#{acc}#{key}: #{value}\n" }.strip
|
207
|
+
Uffizzi.ui.say(deployment_data)
|
198
208
|
end
|
199
209
|
|
200
210
|
def hide_secrets(secret_variables)
|
@@ -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)
|
@@ -246,15 +240,83 @@ module Uffizzi
|
|
246
240
|
Uffizzi.ui.say(preview_url) if success
|
247
241
|
else
|
248
242
|
deployment_data = build_deployment_data(deployment)
|
249
|
-
Uffizzi.ui.
|
243
|
+
Uffizzi.ui.enable_stdout
|
244
|
+
Uffizzi.ui.say(deployment_data)
|
250
245
|
end
|
251
246
|
end
|
252
247
|
|
253
248
|
def build_deployment_data(deployment)
|
249
|
+
url_server = ConfigFile.read_option(:server)
|
250
|
+
|
254
251
|
{
|
255
252
|
id: "deployment-#{deployment[:id]}",
|
256
253
|
url: "https://#{deployment[:preview_url]}",
|
254
|
+
containers_uri: "#{url_server}/projects/#{deployment[:project_id]}/deployments/#{deployment[:id]}/containers",
|
257
255
|
}
|
258
256
|
end
|
257
|
+
|
258
|
+
def build_compose_file_params(file_path)
|
259
|
+
begin
|
260
|
+
compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
|
261
|
+
rescue Errno::ENOENT => e
|
262
|
+
raise Uffizzi::Error.new(e.message)
|
263
|
+
end
|
264
|
+
|
265
|
+
compose_file_dir = File.dirname(file_path)
|
266
|
+
dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
|
267
|
+
absolute_path = File.absolute_path(file_path)
|
268
|
+
compose_file_params = {
|
269
|
+
path: absolute_path,
|
270
|
+
content: Base64.encode64(compose_file_data),
|
271
|
+
source: absolute_path,
|
272
|
+
}
|
273
|
+
|
274
|
+
{
|
275
|
+
compose_file: compose_file_params,
|
276
|
+
dependencies: dependencies,
|
277
|
+
}
|
278
|
+
end
|
279
|
+
|
280
|
+
def build_metadata_params(labels)
|
281
|
+
{
|
282
|
+
metadata: {
|
283
|
+
'labels' => parse_params(labels, 'Labels'),
|
284
|
+
},
|
285
|
+
}
|
286
|
+
end
|
287
|
+
|
288
|
+
def build_filter_params(filter_params)
|
289
|
+
{
|
290
|
+
'labels' => parse_params(filter_params, 'Filtering parameters'),
|
291
|
+
}
|
292
|
+
end
|
293
|
+
|
294
|
+
def parse_params(params, params_type)
|
295
|
+
validate_params(params, params_type)
|
296
|
+
params.split(' ').reduce({}) do |acc, param|
|
297
|
+
stringified_keys, value = param.split('=', 2)
|
298
|
+
keys = stringified_keys.split('.', -1)
|
299
|
+
inner_pair = { keys.pop => value }
|
300
|
+
prepared_param = keys.reverse.reduce(inner_pair) { |res, key| { key => res } }
|
301
|
+
merge_params(acc, prepared_param)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def validate_params(params, params_type)
|
306
|
+
params.split(' ').each do |param|
|
307
|
+
stringified_keys, value = param.split('=', 2)
|
308
|
+
raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if value.nil? || stringified_keys.nil? || value.empty?
|
309
|
+
|
310
|
+
keys = stringified_keys.split('.', -1)
|
311
|
+
raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if keys.empty? || keys.any?(&:empty?)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def merge_params(result, param)
|
316
|
+
key = param.keys.first
|
317
|
+
return result.merge(param) unless result.has_key?(key)
|
318
|
+
|
319
|
+
{ key => result[key].merge(merge_params(result[key], param[key])) }
|
320
|
+
end
|
259
321
|
end
|
260
322
|
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
|
data/lib/uffizzi/cli.rb
CHANGED
@@ -24,6 +24,14 @@ module Uffizzi
|
|
24
24
|
Login.new(options).run
|
25
25
|
end
|
26
26
|
|
27
|
+
desc 'login_by_identity_token [OPTIONS]', 'Login or register to Uffizzi to view and manage your previews'
|
28
|
+
method_option :server, required: true, aliases: '-s'
|
29
|
+
method_option :token, required: true, aliases: '-t'
|
30
|
+
def login_by_identity_token
|
31
|
+
require_relative 'cli/login_by_identity_token'
|
32
|
+
LoginByIdentityToken.new(options).run
|
33
|
+
end
|
34
|
+
|
27
35
|
desc 'logout', 'Log out of a Uffizzi user account'
|
28
36
|
def logout
|
29
37
|
require_relative 'cli/logout'
|
@@ -13,6 +13,13 @@ module ApiClient
|
|
13
13
|
build_response(response)
|
14
14
|
end
|
15
15
|
|
16
|
+
def create_ci_session(server, params = {})
|
17
|
+
uri = ci_session_uri(server)
|
18
|
+
response = http_client.make_post_request(uri, params)
|
19
|
+
|
20
|
+
build_response(response)
|
21
|
+
end
|
22
|
+
|
16
23
|
def destroy_session(server)
|
17
24
|
uri = session_uri(server)
|
18
25
|
response = http_client.make_delete_request(uri)
|
@@ -27,16 +34,16 @@ module ApiClient
|
|
27
34
|
build_response(response)
|
28
35
|
end
|
29
36
|
|
30
|
-
def fetch_credentials(server)
|
31
|
-
uri = credentials_uri(server)
|
37
|
+
def fetch_credentials(server, account_id)
|
38
|
+
uri = credentials_uri(server, account_id)
|
32
39
|
|
33
40
|
response = http_client.make_get_request(uri)
|
34
41
|
|
35
42
|
build_response(response)
|
36
43
|
end
|
37
44
|
|
38
|
-
def check_credential(server, type)
|
39
|
-
uri = check_credential_uri(server, type)
|
45
|
+
def check_credential(server, account_id, type)
|
46
|
+
uri = check_credential_uri(server, account_id, type)
|
40
47
|
response = http_client.make_get_request(uri)
|
41
48
|
|
42
49
|
build_response(response)
|
@@ -49,8 +56,8 @@ module ApiClient
|
|
49
56
|
build_response(response)
|
50
57
|
end
|
51
58
|
|
52
|
-
def create_project(server, params)
|
53
|
-
uri =
|
59
|
+
def create_project(server, account_id, params)
|
60
|
+
uri = create_projects_uri(server, account_id)
|
54
61
|
response = http_client.make_post_request(uri, params)
|
55
62
|
|
56
63
|
build_response(response)
|
@@ -63,15 +70,15 @@ module ApiClient
|
|
63
70
|
build_response(response)
|
64
71
|
end
|
65
72
|
|
66
|
-
def create_credential(server, params)
|
67
|
-
uri = credentials_uri(server)
|
73
|
+
def create_credential(server, account_id, params)
|
74
|
+
uri = credentials_uri(server, account_id)
|
68
75
|
response = http_client.make_post_request(uri, params)
|
69
76
|
|
70
77
|
build_response(response)
|
71
78
|
end
|
72
79
|
|
73
|
-
def update_credential(server, params, type)
|
74
|
-
uri = credential_uri(server, type)
|
80
|
+
def update_credential(server, account_id, params, type)
|
81
|
+
uri = credential_uri(server, account_id, type)
|
75
82
|
response = http_client.make_put_request(uri, params)
|
76
83
|
|
77
84
|
build_response(response)
|
@@ -84,8 +91,8 @@ module ApiClient
|
|
84
91
|
build_response(response)
|
85
92
|
end
|
86
93
|
|
87
|
-
def delete_credential(server, credential_type)
|
88
|
-
uri = credential_uri(server, credential_type)
|
94
|
+
def delete_credential(server, account_id, credential_type)
|
95
|
+
uri = credential_uri(server, account_id, credential_type)
|
89
96
|
response = http_client.make_delete_request(uri)
|
90
97
|
|
91
98
|
build_response(response)
|
@@ -147,8 +154,8 @@ module ApiClient
|
|
147
154
|
build_response(response)
|
148
155
|
end
|
149
156
|
|
150
|
-
def fetch_deployments(server, project_slug)
|
151
|
-
uri = deployments_uri(server, project_slug)
|
157
|
+
def fetch_deployments(server, project_slug, filter)
|
158
|
+
uri = deployments_uri(server, project_slug, filter)
|
152
159
|
response = http_client.make_get_request(uri)
|
153
160
|
|
154
161
|
build_response(response)
|
@@ -15,6 +15,10 @@ module ApiRoutes
|
|
15
15
|
"#{server}/api/cli/v1/projects"
|
16
16
|
end
|
17
17
|
|
18
|
+
def create_projects_uri(server, account_id)
|
19
|
+
"#{server}/api/cli/v1/accounts/#{account_id}/projects"
|
20
|
+
end
|
21
|
+
|
18
22
|
def secret_uri(server, project_slug, id)
|
19
23
|
path_id = CGI.escape(id)
|
20
24
|
"#{server}/api/cli/v1/projects/#{project_slug}/secrets/#{path_id}"
|
@@ -28,12 +32,18 @@ module ApiRoutes
|
|
28
32
|
"#{server}/api/cli/v1/session"
|
29
33
|
end
|
30
34
|
|
35
|
+
def ci_session_uri(server)
|
36
|
+
"#{server}/api/cli/v1/ci/session"
|
37
|
+
end
|
38
|
+
|
31
39
|
def validate_compose_file_uri(server, project_slug)
|
32
40
|
"#{compose_files_uri(server, project_slug)}/validate"
|
33
41
|
end
|
34
42
|
|
35
|
-
def deployments_uri(server, project_slug)
|
36
|
-
"#{server}/api/cli/v1/projects/#{project_slug}/deployments"
|
43
|
+
def deployments_uri(server, project_slug, filter = nil)
|
44
|
+
return "#{server}/api/cli/v1/projects/#{project_slug}/deployments" if filter.nil?
|
45
|
+
|
46
|
+
"#{server}/api/cli/v1/projects/#{project_slug}/deployments?q=#{filter.to_json}"
|
37
47
|
end
|
38
48
|
|
39
49
|
def deployment_uri(server, project_slug, deployment_id)
|
@@ -52,20 +62,20 @@ module ApiRoutes
|
|
52
62
|
"#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/events"
|
53
63
|
end
|
54
64
|
|
55
|
-
def check_credential_uri(server, type)
|
56
|
-
"#{server}/api/cli/v1/
|
65
|
+
def check_credential_uri(server, account_id, type)
|
66
|
+
"#{server}/api/cli/v1/accounts/#{account_id}/credentials/#{type}/check_credential"
|
57
67
|
end
|
58
68
|
|
59
|
-
def credentials_uri(server)
|
60
|
-
"#{server}/api/cli/v1/
|
69
|
+
def credentials_uri(server, account_id)
|
70
|
+
"#{server}/api/cli/v1/accounts/#{account_id}/credentials"
|
61
71
|
end
|
62
72
|
|
63
73
|
def preview_services_uri(server, project_slug, deployment_id)
|
64
74
|
"#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers"
|
65
75
|
end
|
66
76
|
|
67
|
-
def credential_uri(server, credential_type)
|
68
|
-
"#{server}/api/cli/v1/
|
77
|
+
def credential_uri(server, account_id, credential_type)
|
78
|
+
"#{server}/api/cli/v1/accounts/#{account_id}/credentials/#{credential_type}"
|
69
79
|
end
|
70
80
|
|
71
81
|
def preview_service_logs_uri(server, project_slug, deployment_id, container_name)
|
@@ -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
|
@@ -24,6 +24,7 @@ class ProjectService
|
|
24
24
|
Uffizzi.ui.say("Project name: #{project[:name]}")
|
25
25
|
Uffizzi.ui.say("Project slug: #{project[:slug]}")
|
26
26
|
Uffizzi.ui.say("Description: #{project[:description]}".strip)
|
27
|
+
Uffizzi.ui.say("Account name: #{project[:account][:name]}".strip)
|
27
28
|
Uffizzi.ui.say("Created: #{project[:created_at]}")
|
28
29
|
default_compose = project[:default_compose].nil? ? nil : project[:default_compose][:source]
|
29
30
|
Uffizzi.ui.say("Default compose: #{default_compose}".strip)
|
data/lib/uffizzi/shell.rb
CHANGED
@@ -7,12 +7,26 @@ module Uffizzi
|
|
7
7
|
class Shell
|
8
8
|
attr_accessor :output_format
|
9
9
|
|
10
|
+
PRETTY_JSON = 'pretty-json'
|
11
|
+
REGULAR_JSON = 'json'
|
12
|
+
GITHUB_ACTION = 'github-action'
|
13
|
+
|
10
14
|
def initialize
|
11
15
|
@shell = Thor::Shell::Basic.new
|
12
16
|
end
|
13
17
|
|
14
18
|
def say(message)
|
15
|
-
|
19
|
+
formatted_message = case output_format
|
20
|
+
when PRETTY_JSON
|
21
|
+
format_to_pretty_json(message)
|
22
|
+
when REGULAR_JSON
|
23
|
+
format_to_json(message)
|
24
|
+
when GITHUB_ACTION
|
25
|
+
format_to_github_action(message)
|
26
|
+
else
|
27
|
+
message
|
28
|
+
end
|
29
|
+
@shell.say(formatted_message)
|
16
30
|
end
|
17
31
|
|
18
32
|
def print_in_columns(messages)
|
@@ -34,33 +48,28 @@ module Uffizzi
|
|
34
48
|
@shell.send(:stdout).string.strip
|
35
49
|
end
|
36
50
|
|
37
|
-
def pretty_say(collection, index = true)
|
38
|
-
ap(collection, { index: index })
|
39
|
-
end
|
40
|
-
|
41
51
|
def disable_stdout
|
42
52
|
$stdout = StringIO.new
|
43
53
|
end
|
44
54
|
|
45
|
-
def
|
55
|
+
def enable_stdout
|
46
56
|
$stdout = IO.new(1, 'w')
|
47
|
-
json_format? ? output_in_json(data) : output_in_github_format(data)
|
48
57
|
end
|
49
58
|
|
50
59
|
private
|
51
60
|
|
52
|
-
def
|
53
|
-
|
61
|
+
def format_to_json(data)
|
62
|
+
data.to_json
|
54
63
|
end
|
55
64
|
|
56
|
-
def
|
57
|
-
|
65
|
+
def format_to_pretty_json(data)
|
66
|
+
JSON.pretty_generate(data)
|
58
67
|
end
|
59
68
|
|
60
|
-
def
|
61
|
-
data.
|
62
|
-
|
63
|
-
|
69
|
+
def format_to_github_action(data)
|
70
|
+
return '' unless data.is_a?(Hash)
|
71
|
+
|
72
|
+
data.reduce('') { |acc, (key, value)| "#{acc}::set-output name=#{key}::#{value}\n" }
|
64
73
|
end
|
65
74
|
end
|
66
75
|
end
|
data/lib/uffizzi/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
.\" generated with Ronn-NG/v0.9.1
|
2
|
+
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
+
.TH "UFFIZZI\-LOGIN\-BY\-IDENTITY\-TOKEN" "" "August 2022" ""
|
4
|
+
.SH "NAME"
|
5
|
+
\fBuffizzi\-login\-by\-identity\-token\fR \- login to Uffizzi using a OIDC token provided by a CI/CD pipeline
|
6
|
+
.SH "SYNOPSIS"
|
7
|
+
.nf
|
8
|
+
uffizzi uffizzi\-login\-by\-identity\-token [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
|
9
|
+
.fi
|
10
|
+
.SH "DESCRIPTION"
|
11
|
+
.nf
|
12
|
+
The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline\.
|
13
|
+
If a user/account do not exist, Uffizzi will create them based on token payload\.
|
14
|
+
|
15
|
+
For more information on authentication and credential types, see:
|
16
|
+
https://github\.com/UffizziCloud/uffizzi_cli
|
17
|
+
.fi
|
18
|
+
.SH "UFFIZZI WIDE FLAGS"
|
19
|
+
.nf
|
20
|
+
These flags are available to all commands: \-\-project\. Run $ uffizzi
|
21
|
+
help for details\.
|
22
|
+
.fi
|
23
|
+
.SH "EXAMPLES"
|
24
|
+
.nf
|
25
|
+
To login from the CI/CD pipeline, run:
|
26
|
+
|
27
|
+
$ uffizzi uffizzi\-login\-by\-identity\-token \-\-server=uffizzi\.example\.com \-\-token=[$CI_JOB_TOKEN]
|
28
|
+
.fi
|
29
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv='content-type' content='text/html;charset=utf8'>
|
5
|
+
<meta name='generator' content='Ronn-NG/v0.9.1 (http://github.com/apjanke/ronn-ng/tree/0.9.1)'>
|
6
|
+
<title>login to Uffizzi using a OIDC token provided by a CI/CD pipeline</title>
|
7
|
+
<style type='text/css' media='all'>
|
8
|
+
/* style: man */
|
9
|
+
body#manpage {margin:0}
|
10
|
+
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
|
11
|
+
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
|
12
|
+
.mp h2 {margin:10px 0 0 0}
|
13
|
+
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
|
14
|
+
.mp h3 {margin:0 0 0 4ex}
|
15
|
+
.mp dt {margin:0;clear:left}
|
16
|
+
.mp dt.flush {float:left;width:8ex}
|
17
|
+
.mp dd {margin:0 0 0 9ex}
|
18
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
|
19
|
+
.mp pre {margin-bottom:20px}
|
20
|
+
.mp pre+h2,.mp pre+h3 {margin-top:22px}
|
21
|
+
.mp h2+pre,.mp h3+pre {margin-top:5px}
|
22
|
+
.mp img {display:block;margin:auto}
|
23
|
+
.mp h1.man-title {display:none}
|
24
|
+
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
|
25
|
+
.mp h2 {font-size:16px;line-height:1.25}
|
26
|
+
.mp h1 {font-size:20px;line-height:2}
|
27
|
+
.mp {text-align:justify;background:#fff}
|
28
|
+
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
|
29
|
+
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
|
30
|
+
.mp u {text-decoration:underline}
|
31
|
+
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
|
32
|
+
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
|
33
|
+
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
|
34
|
+
.mp b.man-ref {font-weight:normal;color:#434241}
|
35
|
+
.mp pre {padding:0 4ex}
|
36
|
+
.mp pre code {font-weight:normal;color:#434241}
|
37
|
+
.mp h2+pre,h3+pre {padding-left:0}
|
38
|
+
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
|
39
|
+
ol.man-decor {width:100%}
|
40
|
+
ol.man-decor li.tl {text-align:left}
|
41
|
+
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
|
42
|
+
ol.man-decor li.tr {text-align:right;float:right}
|
43
|
+
</style>
|
44
|
+
</head>
|
45
|
+
<!--
|
46
|
+
The following styles are deprecated and will be removed at some point:
|
47
|
+
div#man, div#man ol.man, div#man ol.head, div#man ol.man.
|
48
|
+
|
49
|
+
The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
|
50
|
+
.man-navigation should be used instead.
|
51
|
+
-->
|
52
|
+
<body id='manpage'>
|
53
|
+
<div class='mp' id='man'>
|
54
|
+
|
55
|
+
<div class='man-navigation' style='display:none'>
|
56
|
+
<a href="#NAME">NAME</a>
|
57
|
+
<a href="#SYNOPSIS">SYNOPSIS</a>
|
58
|
+
<a href="#DESCRIPTION">DESCRIPTION</a>
|
59
|
+
<a href="#UFFIZZI-WIDE-FLAGS">UFFIZZI WIDE FLAGS</a>
|
60
|
+
<a href="#EXAMPLES">EXAMPLES</a>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<ol class='man-decor man-head man head'>
|
64
|
+
<li class='tl'>uffizzi-login-by-identity-token</li>
|
65
|
+
<li class='tc'></li>
|
66
|
+
<li class='tr'>uffizzi-login-by-identity-token</li>
|
67
|
+
</ol>
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
<h2 id="NAME">NAME</h2>
|
72
|
+
<p class="man-name">
|
73
|
+
<code>uffizzi-login-by-identity-token</code> - <span class="man-whatis">login to Uffizzi using a OIDC token provided by a CI/CD pipeline</span>
|
74
|
+
</p>
|
75
|
+
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
76
|
+
<pre><code>uffizzi uffizzi-login-by-identity-token [UFFIZZI_WIDE_FLAG ...]
|
77
|
+
</code></pre>
|
78
|
+
|
79
|
+
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
80
|
+
<pre><code>The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline.
|
81
|
+
If a user/account do not exist, Uffizzi will create them based on token payload.
|
82
|
+
|
83
|
+
For more information on authentication and credential types, see:
|
84
|
+
https://github.com/UffizziCloud/uffizzi_cli
|
85
|
+
</code></pre>
|
86
|
+
|
87
|
+
<h2 id="UFFIZZI-WIDE-FLAGS">UFFIZZI WIDE FLAGS</h2>
|
88
|
+
<pre><code>These flags are available to all commands: --project. Run $ uffizzi
|
89
|
+
help for details.
|
90
|
+
</code></pre>
|
91
|
+
|
92
|
+
<h2 id="EXAMPLES">EXAMPLES</h2>
|
93
|
+
<pre><code>To login from the CI/CD pipeline, run:
|
94
|
+
|
95
|
+
$ uffizzi uffizzi-login-by-identity-token --server=uffizzi.example.com --token=[$CI_JOB_TOKEN]
|
96
|
+
</code></pre>
|
97
|
+
|
98
|
+
<ol class='man-decor man-foot man foot'>
|
99
|
+
<li class='tl'></li>
|
100
|
+
<li class='tc'>August 2022</li>
|
101
|
+
<li class='tr'>uffizzi-login-by-identity-token</li>
|
102
|
+
</ol>
|
103
|
+
|
104
|
+
</div>
|
105
|
+
</body>
|
106
|
+
</html>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
uffizzi-login-by-identity-token - login to Uffizzi using a OIDC token provided by a CI/CD pipeline
|
2
|
+
================================================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
uffizzi uffizzi-login-by-identity-token [UFFIZZI_WIDE_FLAG ...]
|
6
|
+
|
7
|
+
## DESCRIPTION
|
8
|
+
The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline.
|
9
|
+
If a user/account do not exist, Uffizzi will create them based on token payload.
|
10
|
+
|
11
|
+
For more information on authentication and credential types, see:
|
12
|
+
https://github.com/UffizziCloud/uffizzi_cli
|
13
|
+
|
14
|
+
## UFFIZZI WIDE FLAGS
|
15
|
+
These flags are available to all commands: --project. Run $ uffizzi
|
16
|
+
help for details.
|
17
|
+
|
18
|
+
## EXAMPLES
|
19
|
+
To login from the CI/CD pipeline, run:
|
20
|
+
|
21
|
+
$ uffizzi uffizzi-login-by-identity-token --server=uffizzi.example.com --token=[$CI_JOB_TOKEN]
|
data/man/uffizzi-preview-create
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
.\" generated with Ronn-NG/v0.9.1
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
-
.TH "UFFIZZI\-PREVIEW\-CREATE" "" "
|
3
|
+
.TH "UFFIZZI\-PREVIEW\-CREATE" "" "August 2022" ""
|
4
4
|
.SH "NAME"
|
5
5
|
\fBuffizzi\-preview\-create\fR \- create a preview
|
6
6
|
.SH "SYNOPSIS"
|
@@ -32,6 +32,12 @@ https://github\.com/UffizziCloud/uffizzi_cli
|
|
32
32
|
the previews they create: when the preview is deleted, the
|
33
33
|
alternate compose is deleted by the Uffizzi API\.
|
34
34
|
.fi
|
35
|
+
.SH "FLAGS"
|
36
|
+
.nf
|
37
|
+
\-\-set\-labels=METADATA
|
38
|
+
Metadata of deployment that contains any information which can
|
39
|
+
be usefull for filtering deployments\.
|
40
|
+
.fi
|
35
41
|
.SH "UFFIZZI WIDE FLAGS"
|
36
42
|
.nf
|
37
43
|
These flags are available to all commands: \-\-project\. Run $ uffizzi
|
@@ -46,5 +52,14 @@ To create a preview with the project\'s default compose file, run:
|
|
46
52
|
To create a preview with an alternate compose file, run:
|
47
53
|
|
48
54
|
$ uffizzi preview create docker\-compose\.uffizzi\.alt\.yml
|
55
|
+
|
56
|
+
To create a preview with single label, run:
|
57
|
+
|
58
|
+
$ uffizzi preview create \-\-set\-labels github\.repo=my_repo
|
59
|
+
|
60
|
+
To create a preview with multiple labels, run:
|
61
|
+
|
62
|
+
$ uffizzi preview create \e
|
63
|
+
\-\-set\-labels="github\.repo=my_repo github\.pull_request\.number=23"
|
49
64
|
.fi
|
50
65
|
|
@@ -27,6 +27,11 @@ uffizzi-preview-create - create a preview
|
|
27
27
|
the previews they create: when the preview is deleted, the
|
28
28
|
alternate compose is deleted by the Uffizzi API.
|
29
29
|
|
30
|
+
## FLAGS
|
31
|
+
--set-labels=METADATA
|
32
|
+
Metadata of deployment that contains any information which can
|
33
|
+
be usefull for filtering deployments.
|
34
|
+
|
30
35
|
## UFFIZZI WIDE FLAGS
|
31
36
|
These flags are available to all commands: --project. Run $ uffizzi
|
32
37
|
help for details.
|
@@ -39,3 +44,12 @@ uffizzi-preview-create - create a preview
|
|
39
44
|
To create a preview with an alternate compose file, run:
|
40
45
|
|
41
46
|
$ uffizzi preview create docker-compose.uffizzi.alt.yml
|
47
|
+
|
48
|
+
To create a preview with single label, run:
|
49
|
+
|
50
|
+
$ uffizzi preview create --set-labels github.repo=my_repo
|
51
|
+
|
52
|
+
To create a preview with multiple labels, run:
|
53
|
+
|
54
|
+
$ uffizzi preview create \
|
55
|
+
--set-labels="github.repo=my_repo github.pull_request.number=23"
|
data/man/uffizzi-preview-list
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
.\" generated with Ronn-NG/v0.9.1
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
-
.TH "UFFIZZI\-PREVIEW\-LIST" "" "
|
3
|
+
.TH "UFFIZZI\-PREVIEW\-LIST" "" "September 2022" ""
|
4
4
|
.SH "NAME"
|
5
5
|
\fBuffizzi\-preview\-list\fR \- list previews in a project
|
6
6
|
.SH "SYNOPSIS"
|
@@ -15,6 +15,15 @@ deploying and failed previews\.
|
|
15
15
|
For more information on Uffizzi previews, see:
|
16
16
|
https://github\.com/UffizziCloud/uffizzi_cli
|
17
17
|
.fi
|
18
|
+
.SH "FLAGS"
|
19
|
+
.nf
|
20
|
+
\-\-filter=METADATA
|
21
|
+
Metadata to filtering list of deployments\.
|
22
|
+
|
23
|
+
\-\-output=pretty\-json
|
24
|
+
Use this option for a more detailed description of listed
|
25
|
+
deployments\.
|
26
|
+
.fi
|
18
27
|
.SH "UFFIZZI WIDE FLAGS"
|
19
28
|
.nf
|
20
29
|
These flags are available to all commands: \-\-project\. Run $ uffizzi
|
@@ -29,5 +38,20 @@ To list all previews in the default project, run:
|
|
29
38
|
To list all previews in a project with name my_project, run:
|
30
39
|
|
31
40
|
$ uffizzi preview list \-\-project="my_project"
|
41
|
+
|
42
|
+
To list all previews in json format, run:
|
43
|
+
|
44
|
+
$ uffizzi preview list \-\-output="pretty\-json"
|
45
|
+
|
46
|
+
To list all previews filtered by metadata using single
|
47
|
+
label, run:
|
48
|
+
|
49
|
+
$ uffizzi preview list \-\-filter github\.repo=my_repo
|
50
|
+
|
51
|
+
To list all previews filtered by metadata using multiple
|
52
|
+
labels, run:
|
53
|
+
|
54
|
+
$ uffizzi preview list \e
|
55
|
+
\-\-filter="github\.repo=my_repo github\.pull_request\.number=23"
|
32
56
|
.fi
|
33
57
|
|
@@ -11,6 +11,14 @@ uffizzi-preview-list - list previews in a project
|
|
11
11
|
For more information on Uffizzi previews, see:
|
12
12
|
https://github.com/UffizziCloud/uffizzi_cli
|
13
13
|
|
14
|
+
## FLAGS
|
15
|
+
--filter=METADATA
|
16
|
+
Metadata to filtering list of deployments.
|
17
|
+
|
18
|
+
--output=pretty-json
|
19
|
+
Use this option for a more detailed description of listed
|
20
|
+
deployments.
|
21
|
+
|
14
22
|
## UFFIZZI WIDE FLAGS
|
15
23
|
These flags are available to all commands: --project. Run $ uffizzi
|
16
24
|
help for details.
|
@@ -23,3 +31,18 @@ uffizzi-preview-list - list previews in a project
|
|
23
31
|
To list all previews in a project with name my_project, run:
|
24
32
|
|
25
33
|
$ uffizzi preview list --project="my_project"
|
34
|
+
|
35
|
+
To list all previews in json format, run:
|
36
|
+
|
37
|
+
$ uffizzi preview list --output="pretty-json"
|
38
|
+
|
39
|
+
To list all previews filtered by metadata using single
|
40
|
+
label, run:
|
41
|
+
|
42
|
+
$ uffizzi preview list --filter github.repo=my_repo
|
43
|
+
|
44
|
+
To list all previews filtered by metadata using multiple
|
45
|
+
labels, run:
|
46
|
+
|
47
|
+
$ uffizzi preview list \
|
48
|
+
--filter="github.repo=my_repo github.pull_request.number=23"
|
data/man/uffizzi-preview-update
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
.\" generated with Ronn-NG/v0.9.1
|
2
2
|
.\" http://github.com/apjanke/ronn-ng/tree/0.9.1
|
3
|
-
.TH "UPDATE" "" "
|
3
|
+
.TH "UPDATE" "" "August 2022" ""
|
4
4
|
.SH "NAME"
|
5
|
-
\
|
5
|
+
\fBupdate\fR \- update a preview
|
6
6
|
.SH "SYNOPSIS"
|
7
7
|
.nf
|
8
8
|
uffizzi preview update [PREVIEW_ID] [COMPOSE_FILE] [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
|
@@ -27,6 +27,12 @@ https://github\.com/UffizziCloud/uffizzi_cli
|
|
27
27
|
[COMPOSE_FILE]
|
28
28
|
The new compose file you want to preview\.
|
29
29
|
.fi
|
30
|
+
.SH "FLAGS"
|
31
|
+
.nf
|
32
|
+
\-\-set\-labels=METADATA
|
33
|
+
Metadata of deployment that contains any information which can
|
34
|
+
be usefull for filtering deployments\.
|
35
|
+
.fi
|
30
36
|
.SH "UFFIZZI WIDE FLAGS"
|
31
37
|
.nf
|
32
38
|
These flags are available to all commands: \-\-project\. Run $ uffizzi
|
@@ -38,5 +44,17 @@ The following command updates a preview with ID deployment\-67 using
|
|
38
44
|
compose file docker\-compose\.alt\.yml:
|
39
45
|
|
40
46
|
$ uffizzi preview update deployment\-67 docker\-compose\.alt\.yml
|
47
|
+
|
48
|
+
To update a preview with single label, run:
|
49
|
+
|
50
|
+
$ uffizzi preview update \e
|
51
|
+
deployment\-67 docker\-compose\.alt\.yml \e
|
52
|
+
\-\-set\-labels github\.repo=my_repo
|
53
|
+
|
54
|
+
To update a preview with multiple labels, run:
|
55
|
+
|
56
|
+
$ uffizzi preview update \e
|
57
|
+
deployment\-67 docker\-compose\.alt\.yml \e
|
58
|
+
\-\-set\-labels="github\.repo=my_repo github\.pull_request\.number=23"
|
41
59
|
.fi
|
42
60
|
|
@@ -22,6 +22,11 @@ uffizzi preview update - update a preview
|
|
22
22
|
[COMPOSE_FILE]
|
23
23
|
The new compose file you want to preview.
|
24
24
|
|
25
|
+
## FLAGS
|
26
|
+
--set-labels=METADATA
|
27
|
+
Metadata of deployment that contains any information which can
|
28
|
+
be usefull for filtering deployments.
|
29
|
+
|
25
30
|
## UFFIZZI WIDE FLAGS
|
26
31
|
These flags are available to all commands: --project. Run $ uffizzi
|
27
32
|
help for details.
|
@@ -31,3 +36,15 @@ uffizzi preview update - update a preview
|
|
31
36
|
compose file docker-compose.alt.yml:
|
32
37
|
|
33
38
|
$ uffizzi preview update deployment-67 docker-compose.alt.yml
|
39
|
+
|
40
|
+
To update a preview with single label, run:
|
41
|
+
|
42
|
+
$ uffizzi preview update \
|
43
|
+
deployment-67 docker-compose.alt.yml \
|
44
|
+
--set-labels github.repo=my_repo
|
45
|
+
|
46
|
+
To update a preview with multiple labels, run:
|
47
|
+
|
48
|
+
$ uffizzi preview update \
|
49
|
+
deployment-67 docker-compose.alt.yml \
|
50
|
+
--set-labels="github.repo=my_repo github.pull_request.number=23"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uffizzi-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Thurman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-09-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: awesome_print
|
@@ -325,6 +325,7 @@ files:
|
|
325
325
|
- lib/uffizzi/cli/connect.rb
|
326
326
|
- lib/uffizzi/cli/disconnect.rb
|
327
327
|
- lib/uffizzi/cli/login.rb
|
328
|
+
- lib/uffizzi/cli/login_by_identity_token.rb
|
328
329
|
- lib/uffizzi/cli/logout.rb
|
329
330
|
- lib/uffizzi/cli/preview.rb
|
330
331
|
- lib/uffizzi/cli/preview/service.rb
|
@@ -368,6 +369,9 @@ files:
|
|
368
369
|
- man/uffizzi-disconnect
|
369
370
|
- man/uffizzi-disconnect.ronn
|
370
371
|
- man/uffizzi-login
|
372
|
+
- man/uffizzi-login-by-identity-token
|
373
|
+
- man/uffizzi-login-by-identity-token.html
|
374
|
+
- man/uffizzi-login-by-identity-token.ronn
|
371
375
|
- man/uffizzi-login.ronn
|
372
376
|
- man/uffizzi-logout
|
373
377
|
- man/uffizzi-logout.ronn
|