uffizzi-cli 0.5.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) 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 +2 -2
  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 +109 -64
  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/man/uffizzi-config +65 -0
  30. data/man/uffizzi-config.html +144 -0
  31. data/man/uffizzi-config.ronn +55 -0
  32. data/man/uffizzi-connect +37 -0
  33. data/man/uffizzi-connect-acr +35 -0
  34. data/man/uffizzi-connect-acr.ronn +28 -0
  35. data/man/uffizzi-connect-docker-hub +34 -0
  36. data/man/uffizzi-connect-docker-hub.ronn +27 -0
  37. data/man/uffizzi-connect-ecr +35 -0
  38. data/man/uffizzi-connect-ecr.ronn +28 -0
  39. data/man/uffizzi-connect-gcr +40 -0
  40. data/man/uffizzi-connect-gcr.ronn +32 -0
  41. data/man/uffizzi-connect-ghcr +35 -0
  42. data/man/uffizzi-connect-ghcr.ronn +28 -0
  43. data/man/uffizzi-connect.ronn +31 -0
  44. data/man/uffizzi-disconnect +37 -0
  45. data/man/uffizzi-disconnect.ronn +31 -0
  46. data/man/uffizzi-login +2 -2
  47. data/man/uffizzi-login.ronn +2 -2
  48. data/man/uffizzi-preview-update +34 -0
  49. data/man/uffizzi-preview-update.ronn +33 -0
  50. data/man/uffizzi-project-set-default +34 -0
  51. data/man/uffizzi-project-set-default.html +111 -0
  52. data/man/uffizzi-project-set-default.ronn +26 -0
  53. 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 if !activity_items.empty? && activity_items.count == deployment[:containers].count
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')