uffizzi-cli 0.3.8 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/config/uffizzi.rb +1 -0
  4. data/lib/uffizzi/cli/common.rb +2 -2
  5. data/lib/uffizzi/cli/config.rb +3 -3
  6. data/lib/uffizzi/cli/connect.rb +22 -0
  7. data/lib/uffizzi/cli/disconnect.rb +46 -0
  8. data/lib/uffizzi/cli/logout.rb +4 -0
  9. data/lib/uffizzi/cli/preview/service.rb +40 -3
  10. data/lib/uffizzi/cli/preview.rb +39 -35
  11. data/lib/uffizzi/cli/project/compose.rb +2 -2
  12. data/lib/uffizzi/cli/project/secret.rb +7 -6
  13. data/lib/uffizzi/cli.rb +37 -8
  14. data/lib/uffizzi/clients/api/api_client.rb +16 -0
  15. data/lib/uffizzi/clients/api/api_routes.rb +8 -0
  16. data/lib/uffizzi/clients/api/http_client.rb +1 -3
  17. data/lib/uffizzi/error.rb +5 -0
  18. data/lib/uffizzi/shell.rb +32 -1
  19. data/lib/uffizzi/version.rb +1 -1
  20. data/lib/uffizzi.rb +2 -2
  21. data/man/uffizzi +51 -0
  22. data/man/uffizzi-login +32 -0
  23. data/man/uffizzi-login.html +113 -0
  24. data/man/uffizzi-login.ronn +24 -0
  25. data/man/uffizzi-logout +21 -0
  26. data/man/uffizzi-logout.html +102 -0
  27. data/man/uffizzi-logout.ronn +19 -0
  28. data/man/uffizzi-preview +39 -0
  29. data/man/uffizzi-preview-create +50 -0
  30. data/man/uffizzi-preview-create.html +128 -0
  31. data/man/uffizzi-preview-create.ronn +41 -0
  32. data/man/uffizzi-preview-delete +37 -0
  33. data/man/uffizzi-preview-delete.html +115 -0
  34. data/man/uffizzi-preview-delete.ronn +28 -0
  35. data/man/uffizzi-preview-describe +38 -0
  36. data/man/uffizzi-preview-describe.html +116 -0
  37. data/man/uffizzi-preview-describe.ronn +29 -0
  38. data/man/uffizzi-preview-events +37 -0
  39. data/man/uffizzi-preview-events.html +110 -0
  40. data/man/uffizzi-preview-events.ronn +28 -0
  41. data/man/uffizzi-preview-list +33 -0
  42. data/man/uffizzi-preview-list.html +110 -0
  43. data/man/uffizzi-preview-list.ronn +25 -0
  44. data/man/uffizzi-preview-service-list +38 -0
  45. data/man/uffizzi-preview-service-list.ronn +29 -0
  46. data/man/uffizzi-preview-service-logs +57 -0
  47. data/man/uffizzi-preview-service-logs.ronn +47 -0
  48. data/man/uffizzi-preview.html +120 -0
  49. data/man/uffizzi-preview.ronn +33 -0
  50. data/man/uffizzi-preview_service_logs +57 -0
  51. data/man/uffizzi-preview_service_logs.html +142 -0
  52. data/man/uffizzi-preview_service_logs.ronn +49 -0
  53. data/man/uffizzi-project +47 -0
  54. data/man/uffizzi-project-compose +40 -0
  55. data/man/uffizzi-project-compose-describe +37 -0
  56. data/man/uffizzi-project-compose-describe.html +118 -0
  57. data/man/uffizzi-project-compose-describe.ronn +29 -0
  58. data/man/uffizzi-project-compose-set +66 -0
  59. data/man/uffizzi-project-compose-set.html +149 -0
  60. data/man/uffizzi-project-compose-set.ronn +57 -0
  61. data/man/uffizzi-project-compose-unset +35 -0
  62. data/man/uffizzi-project-compose-unset.html +116 -0
  63. data/man/uffizzi-project-compose-unset.ronn +27 -0
  64. data/man/uffizzi-project-compose.html +123 -0
  65. data/man/uffizzi-project-compose.ronn +34 -0
  66. data/man/uffizzi-project-secret +37 -0
  67. data/man/uffizzi-project-secret-create +29 -0
  68. data/man/uffizzi-project-secret-create.html +110 -0
  69. data/man/uffizzi-project-secret-create.ronn +21 -0
  70. data/man/uffizzi-project-secret-delete +29 -0
  71. data/man/uffizzi-project-secret-delete.html +110 -0
  72. data/man/uffizzi-project-secret-delete.ronn +21 -0
  73. data/man/uffizzi-project-secret-list +28 -0
  74. data/man/uffizzi-project-secret-list.html +110 -0
  75. data/man/uffizzi-project-secret-list.ronn +20 -0
  76. data/man/uffizzi-project-secret.html +119 -0
  77. data/man/uffizzi-project-secret.ronn +30 -0
  78. data/man/uffizzi-project.html +128 -0
  79. data/man/uffizzi-project.ronn +41 -0
  80. data/man/uffizzi.html +132 -0
  81. data/man/uffizzi.ronn +43 -0
  82. metadata +79 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb1b634680d5b45371d1e0969ccae6a1274dca422641142f681437301883ced1
4
- data.tar.gz: 00a09214b98c56b95393c2adc54e0f4f847fa1333f0253f150db777e36ac823a
3
+ metadata.gz: 40afcffb213061f1da3d74393c334423329aabc97a7c28587659e7e1acdd704e
4
+ data.tar.gz: d2507263bca660a24dfdb6e1ba8927633be123810c58c17df0dfe6618744482f
5
5
  SHA512:
6
- metadata.gz: 499d6008cee797d7746bb6ddb614abf5cb214be6c294c55aab037f2970a57a9386b014021f330dccba0e6ca7efab60e9906d6158bf30aaca9775413c305fe3fd
7
- data.tar.gz: 3dd1de55ff606e1878ef1698d4ea132b9dcce9b1a8bb53184b26a7a7eb056bdd0980c6172512d76fde41f9b10ee24ceb1a11bd9f9f4e67520a6f5e6703790624
6
+ metadata.gz: c2399f33b5b86bd33f5051ddbaaaccb8116eb00840b64f4b29fdca4be758442d7e6af77306500ba1be34e77f5c7a556cb8ac8be689a4728879b47d558f86d413
7
+ data.tar.gz: 8b4078751fc9bdcc38f772af6ef8778de4bff5f61a57020eee5f3c2ff1f8b1c7b26c9b0d1b82d8c0ca8049f10a2cbc3c3280675f3ac7cb4aff162f5921a63c58
data/README.md CHANGED
@@ -176,6 +176,20 @@ $ uffizzi config delete OPTION
176
176
 
177
177
  Deletes specified option.
178
178
 
179
+ ### disconnect ###
180
+
181
+ ```
182
+ $ uffizzi disconnect CREDENTIAL_TYPE
183
+ ```
184
+
185
+ Deletes credential of specified type
186
+
187
+ Supported credential types - `docker-hub`, `acr`, `ecr`, `gcr`
188
+
189
+ ## Generate manual
190
+
191
+ In order to generate a manual, create a `.ronn` file having a name pattern like `uffizzi-{command-name}` (for example `uffizzi-project-compose`) in the `man` directory and run `bundle exec ronn man/{filename}.ronn`
192
+
179
193
  ## Git workflow for the app:
180
194
 
181
195
  1. Clone the repository and checkout to `develop` branch
data/config/uffizzi.rb CHANGED
@@ -18,6 +18,7 @@ module Uffizzi
18
18
  azure: 'UffizziCore::Credential::Azure',
19
19
  google: 'UffizziCore::Credential::Google',
20
20
  amazon: 'UffizziCore::Credential::Amazon',
21
+ github_container_registry: 'UffizziCore::Credential::GithubContainerRegistry',
21
22
  }
22
23
  end
23
24
  end
@@ -5,8 +5,8 @@ require 'open3'
5
5
  module Cli
6
6
  class Common
7
7
  class << self
8
- def show_manual(method_name)
9
- manual_doc_path = "man/uffizzi-#{method_name}"
8
+ def show_manual(command_name)
9
+ manual_doc_path = "man/#{command_name}"
10
10
 
11
11
  Open3.pipeline("man #{manual_doc_path}")
12
12
  end
@@ -12,17 +12,17 @@ module Uffizzi
12
12
  run('list')
13
13
  end
14
14
 
15
- desc 'get', 'get'
15
+ desc 'get [PROPERTY]', 'get'
16
16
  def get(property)
17
17
  run('get', property)
18
18
  end
19
19
 
20
- desc 'set', 'set'
20
+ desc 'set [PROPERTY] [VALUE]', 'set'
21
21
  def set(property, value)
22
22
  run('set', property, value)
23
23
  end
24
24
 
25
- desc 'delete', 'delete'
25
+ desc 'delete [PROPERTY]', 'delete'
26
26
  def delete(property)
27
27
  run('delete', property)
28
28
  end
@@ -14,6 +14,8 @@ module Uffizzi
14
14
  handle_azure
15
15
  when 'ecr'
16
16
  handle_amazon
17
+ when 'ghcr'
18
+ handle_github_container_registry
17
19
  when 'gcr'
18
20
  handle_google(credential_file_path)
19
21
  else
@@ -111,6 +113,26 @@ module Uffizzi
111
113
  end
112
114
  end
113
115
 
116
+ def handle_github_container_registry
117
+ username = Uffizzi.ui.ask('Github Username: ')
118
+ password = Uffizzi.ui.ask('Access Token: ', echo: false)
119
+
120
+ params = {
121
+ username: username,
122
+ password: password,
123
+ type: Uffizzi.configuration.credential_types[:github_container_registry],
124
+ }
125
+
126
+ hostname = ConfigFile.read_option(:hostname)
127
+ response = create_credential(hostname, params)
128
+
129
+ if ResponseHelper.created?(response)
130
+ print_success_message('GitHub Container Registry')
131
+ else
132
+ ResponseHelper.handle_failed_response(response)
133
+ end
134
+ end
135
+
114
136
  def prepare_registry_url(registry_url)
115
137
  return registry_url if registry_url.match?(/^(?:http(s)?:\/\/)/)
116
138
 
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uffizzi'
4
+
5
+ module Uffizzi
6
+ class CLI::Disconnect
7
+ include ApiClient
8
+
9
+ def run(credential_type)
10
+ connection_type = case credential_type
11
+ when 'docker-hub'
12
+ Uffizzi.configuration.credential_types[:dockerhub]
13
+ when 'acr'
14
+ Uffizzi.configuration.credential_types[:azure]
15
+ when 'ecr'
16
+ Uffizzi.configuration.credential_types[:amazon]
17
+ when 'gcr'
18
+ Uffizzi.configuration.credential_types[:google]
19
+ when 'ghcr'
20
+ Uffizzi.configuration.credential_types[:github_container_registry]
21
+ else
22
+ raise Uffizzi::Error.new('Unsupported credential type.')
23
+ end
24
+
25
+ response = delete_credential(ConfigFile.read_option(:hostname), connection_type)
26
+
27
+ if ResponseHelper.no_content?(response)
28
+ Uffizzi.ui.say("Successfully disconnected #{connection_name(credential_type)} connection")
29
+ else
30
+ ResponseHelper.handle_failed_response(response)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def connection_name(credential_type)
37
+ {
38
+ 'docker-hub' => 'DockerHub',
39
+ 'acr' => 'ACR',
40
+ 'ecr' => 'ECR',
41
+ 'gcr' => 'GCR',
42
+ 'ghcr' => 'GHCR',
43
+ }[credential_type]
44
+ end
45
+ end
46
+ end
@@ -7,6 +7,10 @@ module Uffizzi
7
7
  class CLI::Logout
8
8
  include ApiClient
9
9
 
10
+ def initialize(options)
11
+ @options = options
12
+ end
13
+
10
14
  def run
11
15
  return Uffizzi.ui.say('You are not logged in') unless Uffizzi::AuthHelper.signed_in?
12
16
 
@@ -9,7 +9,23 @@ module Uffizzi
9
9
  class CLI::Preview::Service < Thor
10
10
  include ApiClient
11
11
 
12
- desc 'list', 'list'
12
+ desc 'logs [LOGS_TYPE] [DEPLOYMENT_ID] [CONTAINER_NAME]', 'logs'
13
+ def logs(logs_type, deployment_name, container_name = args)
14
+ 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
+
17
+ deployment_id = PreviewService.read_deployment_id(deployment_name)
18
+ response = service_logs_response(logs_type, deployment_id, container_name)
19
+ return Uffizzi.ui.say(response[:errors]) if response[:errors]
20
+
21
+ if ResponseHelper.ok?(response)
22
+ handle_succeed_logs_response(response, container_name)
23
+ else
24
+ ResponseHelper.handle_failed_response(response)
25
+ end
26
+ end
27
+
28
+ desc 'logs [DEPLOYMENT_ID]', 'list'
13
29
  def list(deployment_name)
14
30
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
15
31
  return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
@@ -20,7 +36,7 @@ module Uffizzi
20
36
  response = fetch_deployment_services(hostname, project_slug, deployment_id)
21
37
 
22
38
  if ResponseHelper.ok?(response)
23
- handle_succeed_response(response, deployment_name)
39
+ handle_succeed_list_response(response, deployment_name)
24
40
  else
25
41
  ResponseHelper.handle_failed_response(response)
26
42
  end
@@ -28,7 +44,19 @@ module Uffizzi
28
44
 
29
45
  private
30
46
 
31
- def handle_succeed_response(response, deployment_name)
47
+ def service_logs_response(logs_type, deployment_id, container_name)
48
+ project_slug = ConfigFile.read_option(:project)
49
+ hostname = ConfigFile.read_option(:hostname)
50
+
51
+ case logs_type
52
+ when 'container'
53
+ fetch_deployment_service_logs(hostname, project_slug, deployment_id, container_name)
54
+ else
55
+ raise Uffizzi::Error.new('Unknown log type')
56
+ end
57
+ end
58
+
59
+ def handle_succeed_list_response(response, deployment_name)
32
60
  services = response[:body][:containers] || []
33
61
  return Uffizzi.ui.say("There are no services associated with the preview #{deployment_name}") if services.empty?
34
62
 
@@ -36,5 +64,14 @@ module Uffizzi
36
64
  Uffizzi.ui.say(service)
37
65
  end
38
66
  end
67
+
68
+ def handle_succeed_logs_response(response, container_name)
69
+ logs = response[:body][:logs] || []
70
+ return Uffizzi.ui.say("The service #{container_name} has no logs") if logs.empty?
71
+
72
+ logs.each do |log|
73
+ Uffizzi.ui.say(log)
74
+ end
75
+ end
39
76
  end
40
77
  end
@@ -10,56 +10,45 @@ module Uffizzi
10
10
 
11
11
  @spinner
12
12
 
13
- class << self
14
- def help(_shell, _subcommand)
15
- Cli::Common.show_manual(:preview)
16
- end
17
- end
18
-
19
13
  desc 'service', 'service'
20
14
  require_relative 'preview/service'
21
15
  subcommand 'service', Uffizzi::CLI::Preview::Service
22
16
 
23
17
  desc 'list', 'list'
24
18
  def list
25
- return Cli::Common.show_manual(:list) if options[:help]
26
-
27
- run(options, 'list')
19
+ run('list')
28
20
  end
29
21
 
30
- desc 'create', 'create'
22
+ desc 'create [COMPOSE_FILE]', 'create'
23
+ method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
31
24
  def create(file_path = nil)
32
- return Cli::Common.show_manual(:create) if options[:help]
33
-
34
- run(options, 'create', file_path: file_path)
25
+ run('create', file_path: file_path)
35
26
  end
36
27
 
37
- desc 'delete', 'delete'
28
+ desc 'delete [DEPLOYMENT_ID]', 'delete'
38
29
  def delete(deployment_name)
39
- return Cli::Common.show_manual(:delete) if options[:help]
40
-
41
- run(options, 'delete', deployment_name: deployment_name)
30
+ run('delete', deployment_name: deployment_name)
42
31
  end
43
32
 
44
- desc 'describe', 'describe'
33
+ desc 'describe [DEPLOYMENT_ID]', 'describe'
45
34
  def describe(deployment_name)
46
- return Cli::Common.show_manual(:describe) if options[:help]
47
-
48
- run(options, 'describe', deployment_name: deployment_name)
35
+ run('describe', deployment_name: deployment_name)
49
36
  end
50
37
 
51
- desc 'events', 'events'
38
+ desc 'events [DEPLOYMENT_ID]', 'events'
52
39
  def events(deployment_name)
53
- return Cli::Common.show_manual(:events) if options[:help]
54
-
55
- run(options, 'events', deployment_name: deployment_name)
40
+ run('events', deployment_name: deployment_name)
56
41
  end
57
42
 
58
43
  private
59
44
 
60
- def run(options, command, file_path: nil, deployment_name: nil)
61
- return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
62
- return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
45
+ def run(command, file_path: nil, deployment_name: nil)
46
+ unless options[:output].nil?
47
+ Uffizzi.ui.output_format = options[:output]
48
+ Uffizzi.ui.disable_stdout
49
+ end
50
+ 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?
63
52
 
64
53
  project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
65
54
 
@@ -113,7 +102,7 @@ module Uffizzi
113
102
  end
114
103
 
115
104
  def handle_succeed_events_response(response)
116
- Uffizzi.ui.print_in_columns(response[:body][:events])
105
+ Uffizzi.ui.pretty_say(response[:body][:events])
117
106
  end
118
107
 
119
108
  def handle_succeed_create_response(project_slug, response)
@@ -161,6 +150,19 @@ module Uffizzi
161
150
 
162
151
  containers_spinners = create_containers_spinners(activity_items)
163
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)
164
166
  loop do
165
167
  response = get_activity_items(ConfigFile.read_option(:hostname), project_slug, deployment_id)
166
168
  handle_activity_items_response(response)
@@ -172,10 +174,6 @@ module Uffizzi
172
174
 
173
175
  sleep(5)
174
176
  end
175
-
176
- Uffizzi.ui.say('Done')
177
- preview_url = "http://#{deployment[:preview_url]}"
178
- Uffizzi.ui.say(preview_url) if @spinner.success?
179
177
  end
180
178
 
181
179
  def create_containers_spinners(activity_items)
@@ -264,8 +262,7 @@ module Uffizzi
264
262
  begin
265
263
  compose_file_data = File.read(file_path)
266
264
  rescue Errno::ENOENT => e
267
- Uffizzi.ui.say(e)
268
- return
265
+ raise Uffizzi::Error.new(e.message)
269
266
  end
270
267
 
271
268
  compose_file_dir = File.dirname(file_path)
@@ -282,5 +279,12 @@ module Uffizzi
282
279
  dependencies: dependencies,
283
280
  }
284
281
  end
282
+
283
+ def build_output_data(output_data)
284
+ {
285
+ id: "deployment-#{output_data[:id]}",
286
+ url: "https://#{output_data[:preview_url]}",
287
+ }
288
+ end
285
289
  end
286
290
  end
@@ -10,7 +10,7 @@ module Uffizzi
10
10
  class CLI::Project::Compose < Thor
11
11
  include ApiClient
12
12
 
13
- desc 'set', 'set'
13
+ desc 'set [OPTIONS]', 'set'
14
14
  def set
15
15
  run(options, 'set')
16
16
  end
@@ -96,7 +96,7 @@ module Uffizzi
96
96
  begin
97
97
  compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
98
98
  rescue Errno::ENOENT => e
99
- return Uffizzi.ui.say(e)
99
+ raise Uffizzi::Error.new(e.message)
100
100
  end
101
101
 
102
102
  compose_file_dir = File.dirname(file_path)
@@ -14,19 +14,20 @@ module Uffizzi
14
14
  run('list')
15
15
  end
16
16
 
17
- desc 'create', 'Create secrets'
17
+ desc 'create [SECRET_ID]', 'Create secrets from $stdout'
18
18
  def create(id)
19
19
  run('create', id)
20
20
  end
21
21
 
22
- desc 'delete', 'Delete a secret'
22
+ desc 'delete [SECRET_ID]', 'Delete a secret'
23
23
  def delete(id)
24
24
  run('delete', id)
25
25
  end
26
26
 
27
27
  private
28
28
 
29
- def run(command, args = {})
29
+ def run(command, id = nil)
30
+ Cli::Common.show_manual(:project, :secret, command) if options[:help] || args.include?('help')
30
31
  return Uffizzi.ui.say('You are not logged in') unless AuthHelper.signed_in?
31
32
 
32
33
  project_slug = ConfigFile.read_option(:project)
@@ -36,13 +37,13 @@ module Uffizzi
36
37
  when 'list'
37
38
  handle_list_command(project_slug)
38
39
  when 'create'
39
- handle_create_command(project_slug, args)
40
+ handle_create_command(project_slug, id)
40
41
  when 'delete'
41
- handle_delete_command(project_slug, args)
42
+ handle_delete_command(project_slug, id)
42
43
  else
43
44
  error_message = "The subcommand #{command} does not exist, please run 'uffizzi project secret help' \
44
45
  to get the list of available subcommands"
45
- Uffizzi.ui.say(error_message)
46
+ raise Thor::Error.new(error_message)
46
47
  end
47
48
  end
48
49
 
data/lib/uffizzi/cli.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
4
3
  require 'uffizzi'
5
4
 
6
5
  module Uffizzi
7
6
  class CLI < Thor
8
- require_relative 'cli/common'
9
- class_option :help, type: :boolean, aliases: ['-h', 'help']
7
+ def self.exit_on_failure?
8
+ true
9
+ end
10
10
 
11
11
  desc 'version', 'show version'
12
12
  def version
@@ -14,7 +14,7 @@ module Uffizzi
14
14
  Uffizzi.ui.say(Uffizzi::VERSION)
15
15
  end
16
16
 
17
- desc 'login', 'Login into Uffizzi'
17
+ desc 'login [OPTIONS]', 'Login into Uffizzi'
18
18
  method_option :user, required: true, aliases: '-u'
19
19
  method_option :hostname, required: true
20
20
  def login
@@ -23,11 +23,9 @@ module Uffizzi
23
23
  end
24
24
 
25
25
  desc 'logout', 'Logout from Uffizzi'
26
- def logout(help = nil)
27
- return Cli::Common.show_manual(:logout) if help || options[:help]
28
-
26
+ def logout
29
27
  require_relative 'cli/logout'
30
- Logout.new.run
28
+ Logout.new(options).run
31
29
  end
32
30
 
33
31
  desc 'projects', 'projects'
@@ -54,5 +52,36 @@ module Uffizzi
54
52
  require_relative 'cli/connect'
55
53
  Connect.new.run(credential_type, credential_file_path)
56
54
  end
55
+
56
+ desc 'disconect CREDENTIAL_TYPE', 'Disonnect credentials from Uffizzi'
57
+ def disconnect(credential_type)
58
+ require_relative 'cli/disconnect'
59
+ Disconnect.new.run(credential_type)
60
+ end
61
+
62
+ class << self
63
+ protected
64
+
65
+ def dispatch(meth, given_args, given_opts, config)
66
+ args, opts = Thor::Options.split(given_args)
67
+ return Cli::Common.show_manual(filename(args)) if show_help?(args, opts)
68
+
69
+ super
70
+ end
71
+
72
+ private
73
+
74
+ def filename(args)
75
+ args_without_help = args.reject { |arg| arg == 'help' }
76
+ return 'uffizzi' if args_without_help.empty?
77
+
78
+ "uffizzi-#{args_without_help.join('-')}"
79
+ end
80
+
81
+ def show_help?(args, opts)
82
+ help_options = ['--help', '-h', '--help=true']
83
+ args.empty? || args.include?('help') || opts.any? { |opt| help_options.include?(opt) }
84
+ end
85
+ end
57
86
  end
58
87
  end
@@ -41,6 +41,20 @@ module ApiClient
41
41
  build_response(response)
42
42
  end
43
43
 
44
+ def delete_credential(hostname, credential_type)
45
+ uri = delete_credential_uri(hostname, credential_type)
46
+ response = Uffizzi::HttpClient.make_delete_request(uri)
47
+
48
+ build_response(response)
49
+ end
50
+
51
+ def fetch_deployment_service_logs(hostname, project_slug, deployment_id, container_name)
52
+ uri = preview_service_logs_uri(hostname, project_slug, deployment_id, container_name)
53
+ response = Uffizzi::HttpClient.make_get_request(uri)
54
+
55
+ build_response(response)
56
+ end
57
+
44
58
  def set_compose_file(hostname, params, project_slug)
45
59
  uri = compose_file_uri(hostname, project_slug)
46
60
  response = Uffizzi::HttpClient.make_post_request(uri, params)
@@ -153,6 +167,8 @@ module ApiClient
153
167
  return nil if response.body.nil?
154
168
 
155
169
  JSON.parse(response.body, symbolize_names: true)
170
+ rescue JSON::ParserError
171
+ raise Uffizzi::Error.new(response.message)
156
172
  end
157
173
 
158
174
  def response_cookie(response)
@@ -55,4 +55,12 @@ module ApiRoutes
55
55
  def preview_services_uri(hostname, project_slug, deployment_id)
56
56
  "#{hostname}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers"
57
57
  end
58
+
59
+ def delete_credential_uri(hostname, credential_type)
60
+ "#{hostname}/api/cli/v1/account/credentials/#{credential_type}"
61
+ end
62
+
63
+ def preview_service_logs_uri(hostname, project_slug, deployment_id, container_name)
64
+ "#{hostname}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers/#{container_name}/logs"
65
+ end
58
66
  end
@@ -36,9 +36,7 @@ module Uffizzi
36
36
  http.request(request)
37
37
  end
38
38
 
39
- if response.instance_of?(Net::HTTPUnauthorized)
40
- raise StandardError.new('Not authorized')
41
- end
39
+ raise Uffizzi::Error.new('Not authorized') if response.is_a?(Net::HTTPUnauthorized)
42
40
 
43
41
  response
44
42
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uffizzi
4
+ class Error < Thor::Error; end
5
+ end
data/lib/uffizzi/shell.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
3
+ require 'awesome_print'
4
4
 
5
5
  module Uffizzi
6
6
  module UI
7
7
  class Shell
8
+ attr_accessor :output_format
9
+
8
10
  def initialize
9
11
  @shell = Thor::Shell::Basic.new
10
12
  end
@@ -28,6 +30,35 @@ module Uffizzi
28
30
  def last_message
29
31
  @shell.send(:stdout).string.strip
30
32
  end
33
+
34
+ def pretty_say(collection, index = true)
35
+ ap(collection, { index: index })
36
+ end
37
+
38
+ def disable_stdout
39
+ $stdout = StringIO.new
40
+ end
41
+
42
+ def output(data)
43
+ $stdout = IO.new(1, 'w')
44
+ json_format? ? output_in_json(data) : output_in_github_format(data)
45
+ end
46
+
47
+ private
48
+
49
+ def json_format?
50
+ output_format == 'json'
51
+ end
52
+
53
+ def output_in_json(data)
54
+ say(data.to_json)
55
+ end
56
+
57
+ def output_in_github_format(data)
58
+ data.each_key do |key|
59
+ say("::set-output name=#{key}::#{data[key]}")
60
+ end
61
+ end
31
62
  end
32
63
  end
33
64
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '0.3.8'
4
+ VERSION = '0.5.1'
5
5
  end
data/lib/uffizzi.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require 'io/console'
4
4
  require 'tty-spinner'
5
5
 
6
+ require 'thor'
7
+ require 'uffizzi/error'
6
8
  require 'uffizzi/shell'
7
9
  require 'uffizzi/version'
8
10
  require 'uffizzi/clients/api/api_client'
@@ -11,8 +13,6 @@ require 'uffizzi/config_file'
11
13
  require_relative '../config/uffizzi'
12
14
 
13
15
  module Uffizzi
14
- class Error < StandardError; end
15
-
16
16
  class << self
17
17
  def ui
18
18
  @ui ||= Uffizzi::UI::Shell.new