uffizzi-cli 0.5.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +69 -116
  3. data/config/uffizzi.rb +2 -1
  4. data/exe/uffizzi +1 -1
  5. data/lib/uffizzi/auth_helper.rb +3 -8
  6. data/lib/uffizzi/cli/common.rb +3 -3
  7. data/lib/uffizzi/cli/config.rb +38 -12
  8. data/lib/uffizzi/cli/connect.rb +82 -35
  9. data/lib/uffizzi/cli/disconnect.rb +2 -2
  10. data/lib/uffizzi/cli/login.rb +30 -11
  11. data/lib/uffizzi/cli/logout.rb +3 -3
  12. data/lib/uffizzi/cli/preview/service.rb +12 -11
  13. data/lib/uffizzi/cli/preview.rb +70 -127
  14. data/lib/uffizzi/cli/project/compose.rb +22 -26
  15. data/lib/uffizzi/cli/project/secret.rb +25 -14
  16. data/lib/uffizzi/cli/project.rb +33 -9
  17. data/lib/uffizzi/cli.rb +19 -22
  18. data/lib/uffizzi/clients/api/api_client.rb +108 -63
  19. data/lib/uffizzi/clients/api/api_routes.rb +38 -30
  20. data/lib/uffizzi/clients/api/http_client.rb +47 -45
  21. data/lib/uffizzi/config_file.rb +36 -20
  22. data/lib/uffizzi/date_helper.rb +45 -0
  23. data/lib/uffizzi/response_helper.rb +11 -7
  24. data/lib/uffizzi/services/command_service.rb +9 -0
  25. data/lib/uffizzi/services/compose_file_service.rb +3 -0
  26. data/lib/uffizzi/services/preview_service.rb +109 -0
  27. data/lib/uffizzi/shell.rb +7 -4
  28. data/lib/uffizzi/version.rb +1 -1
  29. data/lib/uffizzi.rb +4 -0
  30. data/man/uffizzi-config +65 -0
  31. data/man/uffizzi-config.html +144 -0
  32. data/man/uffizzi-config.ronn +55 -0
  33. data/man/uffizzi-connect +37 -0
  34. data/man/uffizzi-connect-acr +35 -0
  35. data/man/uffizzi-connect-acr.ronn +28 -0
  36. data/man/uffizzi-connect-docker-hub +34 -0
  37. data/man/uffizzi-connect-docker-hub.ronn +27 -0
  38. data/man/uffizzi-connect-ecr +35 -0
  39. data/man/uffizzi-connect-ecr.ronn +28 -0
  40. data/man/uffizzi-connect-gcr +40 -0
  41. data/man/uffizzi-connect-gcr.ronn +32 -0
  42. data/man/uffizzi-connect-ghcr +35 -0
  43. data/man/uffizzi-connect-ghcr.ronn +28 -0
  44. data/man/uffizzi-connect.ronn +31 -0
  45. data/man/uffizzi-disconnect +37 -0
  46. data/man/uffizzi-disconnect.ronn +31 -0
  47. data/man/uffizzi-login +2 -2
  48. data/man/uffizzi-login.ronn +2 -2
  49. data/man/uffizzi-preview-update +34 -0
  50. data/man/uffizzi-preview-update.ronn +33 -0
  51. data/man/uffizzi-project-set-default +34 -0
  52. data/man/uffizzi-project-set-default.html +111 -0
  53. data/man/uffizzi-project-set-default.ronn +26 -0
  54. metadata +26 -2
@@ -3,7 +3,7 @@
3
3
  require 'uffizzi'
4
4
 
5
5
  module Uffizzi
6
- class CLI::Disconnect
6
+ class Cli::Disconnect
7
7
  include ApiClient
8
8
 
9
9
  def run(credential_type)
@@ -22,7 +22,7 @@ module Uffizzi
22
22
  raise Uffizzi::Error.new('Unsupported credential type.')
23
23
  end
24
24
 
25
- response = delete_credential(ConfigFile.read_option(:hostname), connection_type)
25
+ response = delete_credential(ConfigFile.read_option(:server), connection_type)
26
26
 
27
27
  if ResponseHelper.no_content?(response)
28
28
  Uffizzi.ui.say("Successfully disconnected #{connection_name(credential_type)} connection")
@@ -5,7 +5,7 @@ require 'uffizzi/response_helper'
5
5
  require 'uffizzi/clients/api/api_client'
6
6
 
7
7
  module Uffizzi
8
- class CLI::Login
8
+ class Cli::Login
9
9
  include ApiClient
10
10
 
11
11
  def initialize(options)
@@ -13,13 +13,15 @@ module Uffizzi
13
13
  end
14
14
 
15
15
  def run
16
- password = ENV['UFFIZZI_PASSWORD'] || IO::console.getpass('Enter Password: ')
17
-
18
- params = prepare_request_params(password)
19
- response = create_session(@options[:hostname], params)
16
+ Uffizzi.ui.say('Login to Uffizzi to view and manage your previews.')
17
+ server = set_server
18
+ username = set_username
19
+ password = set_password
20
+ params = prepare_request_params(username, password)
21
+ response = create_session(server, params)
20
22
 
21
23
  if ResponseHelper.created?(response)
22
- handle_succeed_response(response)
24
+ handle_succeed_response(response, server, username)
23
25
  else
24
26
  ResponseHelper.handle_failed_response(response)
25
27
  end
@@ -27,20 +29,37 @@ module Uffizzi
27
29
 
28
30
  private
29
31
 
30
- def prepare_request_params(password)
32
+ def set_server
33
+ config_server = ConfigFile.exists? && ConfigFile.option_has_value?(:server) ? ConfigFile.read_option(:server) : nil
34
+ @options[:server] || config_server || Uffizzi.ui.ask('Server: ')
35
+ end
36
+
37
+ def set_username
38
+ config_username = ConfigFile.exists? && ConfigFile.option_has_value?(:username) ? ConfigFile.read_option(:username) : nil
39
+ @options[:username] || config_username || Uffizzi.ui.ask('Username: ')
40
+ end
41
+
42
+ def set_password
43
+ ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password: ', echo: false)
44
+ end
45
+
46
+ def prepare_request_params(username, password)
31
47
  {
32
48
  user: {
33
- email: @options[:user],
34
- password: password.strip,
49
+ email: username,
50
+ password: password,
35
51
  },
36
52
  }
37
53
  end
38
54
 
39
- def handle_succeed_response(response)
55
+ def handle_succeed_response(response, server, username)
40
56
  account = response[:body][:user][:accounts].first
41
57
  return Uffizzi.ui.say('No account related to this email') unless account_valid?(account)
42
58
 
43
- ConfigFile.create(account[:id], response[:headers], @options[:hostname])
59
+ ConfigFile.write_option(:server, server)
60
+ ConfigFile.write_option(:username, username)
61
+ ConfigFile.write_option(:cookie, response[:headers])
62
+ ConfigFile.write_option(:account_id, account[:id])
44
63
  end
45
64
 
46
65
  def account_valid?(account)
@@ -4,7 +4,7 @@ require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
 
6
6
  module Uffizzi
7
- class CLI::Logout
7
+ class Cli::Logout
8
8
  include ApiClient
9
9
 
10
10
  def initialize(options)
@@ -14,8 +14,8 @@ module Uffizzi
14
14
  def run
15
15
  return Uffizzi.ui.say('You are not logged in') unless Uffizzi::AuthHelper.signed_in?
16
16
 
17
- hostname = ConfigFile.read_option(:hostname)
18
- destroy_session(hostname)
17
+ server = ConfigFile.read_option(:server)
18
+ destroy_session(server)
19
19
 
20
20
  ConfigFile.delete
21
21
  Uffizzi.ui.say('You have been successfully logged out')
@@ -4,15 +4,16 @@ require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
6
  require 'uffizzi/services/preview_service'
7
+ require 'uffizzi/services/command_service'
7
8
 
8
9
  module Uffizzi
9
- class CLI::Preview::Service < Thor
10
+ class Cli::Preview::Service < Thor
10
11
  include ApiClient
11
12
 
12
- desc 'logs [LOGS_TYPE] [DEPLOYMENT_ID] [CONTAINER_NAME]', 'logs'
13
+ desc 'logs [LOGS_TYPE] [DEPLOYMENT_ID] [CONTAINER_NAME]', 'Show the logs for a container service of a preview'
13
14
  def logs(logs_type, deployment_name, container_name = args)
14
15
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
15
- return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
16
+ return Uffizzi.ui.say('This command needs project to be set in config file') unless CommandService.project_set?(options)
16
17
 
17
18
  deployment_id = PreviewService.read_deployment_id(deployment_name)
18
19
  response = service_logs_response(logs_type, deployment_id, container_name)
@@ -25,15 +26,15 @@ module Uffizzi
25
26
  end
26
27
  end
27
28
 
28
- desc 'logs [DEPLOYMENT_ID]', 'list'
29
+ desc 'list [DEPLOYMENT_ID]', 'List the container services of a given preview'
29
30
  def list(deployment_name)
30
31
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
31
- return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
32
+ return Uffizzi.ui.say('This command needs project to be set in config file') unless CommandService.project_set?(options)
32
33
 
33
- project_slug = ConfigFile.read_option(:project)
34
- hostname = ConfigFile.read_option(:hostname)
34
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
35
+ server = ConfigFile.read_option(:server)
35
36
  deployment_id = PreviewService.read_deployment_id(deployment_name)
36
- response = fetch_deployment_services(hostname, project_slug, deployment_id)
37
+ response = fetch_deployment_services(server, project_slug, deployment_id)
37
38
 
38
39
  if ResponseHelper.ok?(response)
39
40
  handle_succeed_list_response(response, deployment_name)
@@ -45,12 +46,12 @@ module Uffizzi
45
46
  private
46
47
 
47
48
  def service_logs_response(logs_type, deployment_id, container_name)
48
- project_slug = ConfigFile.read_option(:project)
49
- hostname = ConfigFile.read_option(:hostname)
49
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
50
+ server = ConfigFile.read_option(:server)
50
51
 
51
52
  case logs_type
52
53
  when 'container'
53
- fetch_deployment_service_logs(hostname, project_slug, deployment_id, container_name)
54
+ fetch_deployment_service_logs(server, project_slug, deployment_id, container_name)
54
55
  else
55
56
  raise Uffizzi::Error.new('Unknown log type')
56
57
  end
@@ -3,39 +3,43 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/services/preview_service'
6
+ require 'uffizzi/services/command_service'
6
7
 
7
8
  module Uffizzi
8
- class CLI::Preview < Thor
9
+ class Cli::Preview < Thor
9
10
  include ApiClient
10
11
 
11
- @spinner
12
-
13
- desc 'service', 'service'
12
+ desc 'service', 'Show the preview services info'
14
13
  require_relative 'preview/service'
15
- subcommand 'service', Uffizzi::CLI::Preview::Service
16
-
17
- desc 'list', 'list'
14
+ subcommand 'service', Uffizzi::Cli::Preview::Service
15
+ desc 'list', 'List all previews'
18
16
  def list
19
17
  run('list')
20
18
  end
21
19
 
22
- desc 'create [COMPOSE_FILE]', 'create'
20
+ desc 'create [COMPOSE_FILE]', 'Create a preview'
23
21
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
24
22
  def create(file_path = nil)
25
23
  run('create', file_path: file_path)
26
24
  end
27
25
 
28
- desc 'delete [DEPLOYMENT_ID]', 'delete'
26
+ desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'create'
27
+ method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
28
+ def update(deployment_name, file_path)
29
+ run('update', deployment_name: deployment_name, file_path: file_path)
30
+ end
31
+
32
+ desc 'delete [DEPLOYMENT_ID]', 'Delete a preview'
29
33
  def delete(deployment_name)
30
34
  run('delete', deployment_name: deployment_name)
31
35
  end
32
36
 
33
- desc 'describe [DEPLOYMENT_ID]', 'describe'
37
+ desc 'describe [DEPLOYMENT_ID]', 'Display details of a preview'
34
38
  def describe(deployment_name)
35
39
  run('describe', deployment_name: deployment_name)
36
40
  end
37
41
 
38
- desc 'events [DEPLOYMENT_ID]', 'events'
42
+ desc 'events [DEPLOYMENT_ID]', 'Show the deployment event logs for a preview'
39
43
  def events(deployment_name)
40
44
  run('events', deployment_name: deployment_name)
41
45
  end
@@ -48,7 +52,7 @@ module Uffizzi
48
52
  Uffizzi.ui.disable_stdout
49
53
  end
50
54
  raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
51
- raise Uffizzi::Error.new('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
55
+ raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
52
56
 
53
57
  project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
54
58
 
@@ -57,6 +61,8 @@ module Uffizzi
57
61
  handle_list_command(project_slug)
58
62
  when 'create'
59
63
  handle_create_command(file_path, project_slug)
64
+ when 'update'
65
+ handle_update_command(deployment_name, file_path, project_slug)
60
66
  when 'delete'
61
67
  handle_delete_command(deployment_name, project_slug)
62
68
  when 'describe'
@@ -67,7 +73,7 @@ module Uffizzi
67
73
  end
68
74
 
69
75
  def handle_list_command(project_slug)
70
- response = fetch_deployments(ConfigFile.read_option(:hostname), project_slug)
76
+ response = fetch_deployments(ConfigFile.read_option(:server), project_slug)
71
77
 
72
78
  if ResponseHelper.ok?(response)
73
79
  handle_succeed_list_response(response)
@@ -78,137 +84,61 @@ module Uffizzi
78
84
 
79
85
  def handle_create_command(file_path, project_slug)
80
86
  params = file_path.nil? ? {} : prepare_params(file_path)
81
- response = create_deployment(ConfigFile.read_option(:hostname), project_slug, params)
87
+ response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
82
88
 
83
89
  if ResponseHelper.created?(response)
84
- handle_succeed_create_response(project_slug, response)
90
+ deployment = response[:body][:deployment]
91
+ success_message = "Preview created with name deployment-#{deployment[:id]}"
92
+ PreviewService.start_deploy_containers(project_slug, deployment, success_message)
85
93
  else
86
94
  ResponseHelper.handle_failed_response(response)
87
95
  end
96
+ rescue SystemExit, Interrupt, SocketError
97
+ deployment_id = response[:body][:deployment][:id]
98
+ handle_preview_interruption(deployment_id, hostname, project_slug)
88
99
  end
89
100
 
90
- def handle_events_command(deployment_name, project_slug)
101
+ def handle_update_command(deployment_name, file_path, project_slug)
91
102
  deployment_id = PreviewService.read_deployment_id(deployment_name)
92
103
 
93
104
  return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
94
105
 
95
- response = fetch_events(ConfigFile.read_option(:hostname), project_slug, deployment_id)
106
+ params = prepare_params(file_path)
107
+ response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
96
108
 
97
109
  if ResponseHelper.ok?(response)
98
- handle_succeed_events_response(response)
110
+ deployment = response[:body][:deployment]
111
+ success_message = "Preview with ID deployment-#{deployment_id} was successfully updated."
112
+ PreviewService.start_deploy_containers(project_slug, deployment, success_message)
99
113
  else
100
114
  ResponseHelper.handle_failed_response(response)
101
115
  end
102
116
  end
103
117
 
104
- def handle_succeed_events_response(response)
105
- Uffizzi.ui.pretty_say(response[:body][:events])
106
- end
118
+ def handle_events_command(deployment_name, project_slug)
119
+ deployment_id = PreviewService.read_deployment_id(deployment_name)
107
120
 
108
- def handle_succeed_create_response(project_slug, response)
109
- deployment = response[:body][:deployment]
110
- deployment_id = deployment[:id]
111
- params = { id: deployment_id }
121
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
112
122
 
113
- response = deploy_containers(ConfigFile.read_option(:hostname), project_slug, deployment_id, params)
123
+ response = fetch_events(ConfigFile.read_option(:server), project_slug, deployment_id)
114
124
 
115
- if ResponseHelper.no_content?(response)
116
- Uffizzi.ui.say("Preview created with name deployment-#{deployment_id}")
117
- print_deployment_progress(deployment, project_slug)
125
+ if ResponseHelper.ok?(response)
126
+ handle_succeed_events_response(response)
118
127
  else
119
128
  ResponseHelper.handle_failed_response(response)
120
129
  end
121
130
  end
122
131
 
123
- def print_deployment_progress(deployment, project_slug)
124
- deployment_id = deployment[:id]
125
-
126
- @spinner = TTY::Spinner.new('[:spinner] Creating containers...', format: :dots)
127
- @spinner.auto_spin
128
-
129
- activity_items = []
130
-
131
- loop do
132
- response = get_activity_items(ConfigFile.read_option(:hostname), project_slug, deployment_id)
133
- handle_activity_items_response(response)
134
- return unless @spinner.spinning?
135
-
136
- activity_items = response[:body][:activity_items]
137
- break unless activity_items.empty?
138
-
139
- sleep(5)
140
- end
141
-
142
- @spinner.success
143
-
144
- Uffizzi.ui.say('Done')
145
-
146
- @spinner = TTY::Spinner::Multi.new('[:spinner] Deploying preview...', format: :dots, style: {
147
- middle: ' ',
148
- bottom: ' ',
149
- })
150
-
151
- containers_spinners = create_containers_spinners(activity_items)
152
-
153
- wait_containers_deploying(project_slug, deployment_id, containers_spinners)
154
-
155
- if options[:output].nil?
156
- Uffizzi.ui.say('Done')
157
- preview_url = "https://#{deployment[:preview_url]}"
158
- Uffizzi.ui.say(preview_url) if @spinner.success?
159
- else
160
- output_data = build_output_data(deployment)
161
- Uffizzi.ui.output(output_data)
162
- end
163
- end
164
-
165
- def wait_containers_deploying(project_slug, deployment_id, containers_spinners)
166
- loop do
167
- response = get_activity_items(ConfigFile.read_option(:hostname), project_slug, deployment_id)
168
- handle_activity_items_response(response)
169
- return if @spinner.done?
170
-
171
- activity_items = response[:body][:activity_items]
172
- check_activity_items_state(activity_items, containers_spinners)
173
- break if activity_items.all? { |activity_item| activity_item[:state] == 'deployed' || activity_item[:state] == 'failed' }
174
-
175
- sleep(5)
176
- end
177
- end
178
-
179
- def create_containers_spinners(activity_items)
180
- activity_items.map do |activity_item|
181
- container_spinner = @spinner.register("[:spinner] #{activity_item[:name]}")
182
- container_spinner.auto_spin
183
- {
184
- name: activity_item[:name],
185
- spinner: container_spinner,
186
- }
187
- end
188
- end
189
-
190
- def check_activity_items_state(activity_items, containers_spinners)
191
- finished_activity_items = activity_items.filter do |activity_item|
192
- activity_item[:state] == 'deployed' || activity_item[:state] == 'failed'
193
- end
194
- finished_activity_items.each do |activity_item|
195
- container_spinner = containers_spinners.detect { |spinner| spinner[:name] == activity_item[:name] }
196
- spinner = container_spinner[:spinner]
197
- case activity_item[:state]
198
- when 'deployed'
199
- spinner.success
200
- when 'failed'
201
- spinner.error
202
- end
203
- end
132
+ def handle_succeed_events_response(response)
133
+ Uffizzi.ui.pretty_say(response[:body][:events])
204
134
  end
205
135
 
206
136
  def handle_delete_command(deployment_name, project_slug)
207
137
  deployment_id = PreviewService.read_deployment_id(deployment_name)
208
138
 
209
- return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
139
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
210
140
 
211
- response = delete_deployment(ConfigFile.read_option(:hostname), project_slug, deployment_id)
141
+ response = delete_deployment(ConfigFile.read_option(:server), project_slug, deployment_id)
212
142
 
213
143
  if ResponseHelper.no_content?(response)
214
144
  handle_succeed_delete_response(deployment_id)
@@ -220,9 +150,9 @@ module Uffizzi
220
150
  def handle_describe_command(deployment_name, project_slug)
221
151
  deployment_id = PreviewService.read_deployment_id(deployment_name)
222
152
 
223
- return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
153
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
224
154
 
225
- response = describe_deployment(ConfigFile.read_option(:hostname), project_slug, deployment_id)
155
+ response = describe_deployment(ConfigFile.read_option(:server), project_slug, deployment_id)
226
156
 
227
157
  if ResponseHelper.ok?(response)
228
158
  handle_succeed_describe_response(response)
@@ -231,16 +161,9 @@ module Uffizzi
231
161
  end
232
162
  end
233
163
 
234
- def handle_activity_items_response(response)
235
- unless ResponseHelper.ok?(response)
236
- @spinner.error
237
- ResponseHelper.handle_failed_response(response)
238
- end
239
- end
240
-
241
164
  def handle_succeed_list_response(response)
242
165
  deployments = response[:body][:deployments] || []
243
- return Uffizzi.ui.say('The project has no active deployments') if deployments.empty?
166
+ raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
244
167
 
245
168
  deployments.each do |deployment|
246
169
  Uffizzi.ui.say("deployment-#{deployment[:id]}")
@@ -253,11 +176,26 @@ module Uffizzi
253
176
 
254
177
  def handle_succeed_describe_response(response)
255
178
  deployment = response[:body][:deployment]
179
+ deployment[:containers] = deployment[:containers].map do |container|
180
+ unless container[:secret_variables].nil?
181
+ container[:secret_variables] = hide_secrets(container[:secret_variables])
182
+ end
183
+
184
+ container
185
+ end
256
186
  deployment.each_key do |key|
257
187
  Uffizzi.ui.say("#{key}: #{deployment[key]}")
258
188
  end
259
189
  end
260
190
 
191
+ def hide_secrets(secret_variables)
192
+ secret_variables.map do |secret_variable|
193
+ secret_variable[:value] = '******'
194
+
195
+ secret_variable
196
+ end
197
+ end
198
+
261
199
  def prepare_params(file_path)
262
200
  begin
263
201
  compose_file_data = File.read(file_path)
@@ -280,11 +218,16 @@ module Uffizzi
280
218
  }
281
219
  end
282
220
 
283
- def build_output_data(output_data)
284
- {
285
- id: "deployment-#{output_data[:id]}",
286
- url: "https://#{output_data[:preview_url]}",
287
- }
221
+ def handle_preview_interruption(deployment_id, hostname, project_slug)
222
+ deletion_response = delete_deployment(hostname, project_slug, deployment_id)
223
+ deployment_name = "deployment-#{deployment_id}"
224
+ preview_deletion_message = if ResponseHelper.no_content?(deletion_response)
225
+ "The preview #{deployment_name} has been disabled."
226
+ else
227
+ "Couldn't disable the deployment #{deployment_name} - please disable maually."
228
+ end
229
+
230
+ raise Uffizzi::Error.new("The preview creation was interrupted. #{preview_deletion_message}")
288
231
  end
289
232
  end
290
233
  end
@@ -5,52 +5,50 @@ require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
6
  require 'uffizzi/services/compose_file_service'
7
7
  require 'uffizzi/services/env_variables_service'
8
+ require 'uffizzi/services/command_service'
8
9
 
9
10
  module Uffizzi
10
- class CLI::Project::Compose < Thor
11
+ class Cli::Project::Compose < Thor
11
12
  include ApiClient
12
13
 
13
- desc 'set [OPTIONS]', 'set'
14
+ desc 'set [OPTIONS]', 'Set the configuration of a project with a compose file'
14
15
  def set
15
- run(options, 'set')
16
+ run('set')
16
17
  end
17
18
 
18
- desc 'unset', 'unset'
19
+ desc 'unset', 'Unset the compose file for a project'
19
20
  def unset
20
- run(options, 'unset')
21
+ run('unset')
21
22
  end
22
23
 
23
- desc 'describe', 'describe'
24
+ desc 'describe', 'Display details of a compose file'
24
25
  def describe
25
- run(options, 'describe')
26
+ run('describe')
26
27
  end
27
28
 
28
29
  private
29
30
 
30
- def run(options, command)
31
+ def run(command)
31
32
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
32
- return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
33
+ return Uffizzi.ui.say('This command needs project to be set in config file') unless CommandService.project_set?(options)
33
34
 
35
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
34
36
  file_path = options[:file]
35
37
  case command
36
38
  when 'set'
37
- handle_set_command(file_path)
39
+ handle_set_command(project_slug, file_path)
38
40
  when 'unset'
39
- handle_unset_command
41
+ handle_unset_command(project_slug)
40
42
  when 'describe'
41
- handle_describe_command
42
- when 'validate'
43
- handle_validate_command(file_path)
43
+ handle_describe_command(project_slug)
44
44
  end
45
45
  end
46
46
 
47
- def handle_set_command(file_path)
47
+ def handle_set_command(project_slug, file_path)
48
48
  return Uffizzi.ui.say('No file provided') if file_path.nil?
49
49
 
50
- hostname = ConfigFile.read_option(:hostname)
51
- project_slug = ConfigFile.read_option(:project)
52
50
  params = prepare_params(file_path)
53
- response = set_compose_file(hostname, params, project_slug)
51
+ response = set_compose_file(ConfigFile.read_option(:server), params, project_slug)
54
52
 
55
53
  if ResponseHelper.created?(response)
56
54
  Uffizzi.ui.say('compose file created')
@@ -59,10 +57,9 @@ module Uffizzi
59
57
  end
60
58
  end
61
59
 
62
- def handle_unset_command
63
- hostname = ConfigFile.read_option(:hostname)
64
- project_slug = ConfigFile.read_option(:project)
65
- response = unset_compose_file(hostname, project_slug)
60
+ def handle_unset_command(project_slug)
61
+ server = ConfigFile.read_option(:server)
62
+ response = unset_compose_file(server, project_slug)
66
63
 
67
64
  if ResponseHelper.no_content?(response)
68
65
  Uffizzi.ui.say('compose file deleted')
@@ -71,10 +68,9 @@ module Uffizzi
71
68
  end
72
69
  end
73
70
 
74
- def handle_describe_command
75
- hostname = ConfigFile.read_option(:hostname)
76
- project_slug = ConfigFile.read_option(:project)
77
- response = describe_compose_file(hostname, project_slug)
71
+ def handle_describe_command(project_slug)
72
+ server = ConfigFile.read_option(:server)
73
+ response = describe_compose_file(server, project_slug)
78
74
  compose_file = response[:body][:compose_file]
79
75
 
80
76
  if ResponseHelper.ok?(response)
@@ -3,23 +3,25 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
+ require 'uffizzi/date_helper'
6
7
  require 'uffizzi/shell'
8
+ require 'time'
7
9
 
8
10
  module Uffizzi
9
- class CLI::Project::Secret < Thor
11
+ class Cli::Project::Secret < Thor
10
12
  include ApiClient
11
13
 
12
- desc 'list', 'List Secrets'
14
+ desc 'list', 'Show metadata for all secrets of a project'
13
15
  def list
14
16
  run('list')
15
17
  end
16
18
 
17
- desc 'create [SECRET_ID]', 'Create secrets from $stdout'
19
+ desc 'create [SECRET_ID]', 'Create a secret for a project'
18
20
  def create(id)
19
21
  run('create', id)
20
22
  end
21
23
 
22
- desc 'delete [SECRET_ID]', 'Delete a secret'
24
+ desc 'delete [SECRET_ID]', 'Delete a secret for a project'
23
25
  def delete(id)
24
26
  run('delete', id)
25
27
  end
@@ -30,7 +32,7 @@ module Uffizzi
30
32
  Cli::Common.show_manual(:project, :secret, command) if options[:help] || args.include?('help')
31
33
  return Uffizzi.ui.say('You are not logged in') unless AuthHelper.signed_in?
32
34
 
33
- project_slug = ConfigFile.read_option(:project)
35
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
34
36
  return Uffizzi.ui.say('Please use the --project option to specify the project name') if project_slug.nil?
35
37
 
36
38
  case command
@@ -48,33 +50,42 @@ module Uffizzi
48
50
  end
49
51
 
50
52
  def handle_list_command(project_slug)
51
- hostname = ConfigFile.read_option(:hostname)
52
- response = fetch_secrets(hostname, project_slug)
53
- secrets = response[:body][:secrets].map { |secret| [secret[:name]] }
53
+ server = ConfigFile.read_option(:server)
54
+ response = fetch_secrets(server, project_slug)
55
+ secrets = response[:body][:secrets]
56
+
54
57
  return Uffizzi.ui.say('There are no secrets for the project') if secrets.empty?
55
58
 
56
- table_header = 'NAME'
57
- table_data = [[table_header], *secrets]
59
+ current_date = Time.now.utc
60
+ prepared_secrets = secrets.map do |secret|
61
+ [
62
+ secret[:name],
63
+ DateHelper.count_distanse(current_date, Time.parse(secret[:created_at])),
64
+ DateHelper.count_distanse(current_date, Time.parse(secret[:updated_at])),
65
+ ]
66
+ end
67
+ table_header = ['NAME', 'CREATED', 'UPDATED']
68
+ table_data = [table_header, *prepared_secrets]
58
69
  return Uffizzi.ui.print_table(table_data) if ResponseHelper.ok?(response)
59
70
 
60
71
  ResponseHelper.handle_failed_response(response)
61
72
  end
62
73
 
63
74
  def handle_create_command(project_slug, id)
64
- hostname = ConfigFile.read_option(:hostname)
75
+ server = ConfigFile.read_option(:server)
65
76
  secret_value = $stdin.read
66
77
  return Uffizzi.ui.say('Please provide the secret value') if secret_value.nil?
67
78
 
68
79
  params = { secrets: [{ name: id, value: secret_value }] }
69
- response = bulk_create_secrets(hostname, project_slug, params)
80
+ response = bulk_create_secrets(server, project_slug, params)
70
81
  return Uffizzi.ui.say('The secret was successfully created') if ResponseHelper.created?(response)
71
82
 
72
83
  ResponseHelper.handle_failed_response(response)
73
84
  end
74
85
 
75
86
  def handle_delete_command(project_slug, id)
76
- hostname = ConfigFile.read_option(:hostname)
77
- response = delete_secret(hostname, project_slug, id)
87
+ server = ConfigFile.read_option(:server)
88
+ response = delete_secret(server, project_slug, id)
78
89
 
79
90
  if ResponseHelper.no_content?(response)
80
91
  Uffizzi.ui.say('The secret was successfully deleted')