uffizzi-cli 0.3.8 → 0.5.1

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 (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