uffizzi-cli 0.3.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) 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 +38 -34
  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 +14 -0
  15. data/lib/uffizzi/clients/api/api_routes.rb +8 -0
  16. data/lib/uffizzi/error.rb +5 -0
  17. data/lib/uffizzi/shell.rb +27 -2
  18. data/lib/uffizzi/version.rb +1 -1
  19. data/lib/uffizzi.rb +2 -2
  20. data/man/uffizzi +51 -0
  21. data/man/uffizzi-login +32 -0
  22. data/man/uffizzi-login.html +113 -0
  23. data/man/uffizzi-login.ronn +24 -0
  24. data/man/uffizzi-logout +1 -1
  25. data/man/uffizzi-logout.html +102 -0
  26. data/man/uffizzi-preview +2 -2
  27. data/man/{uffizzi-create → uffizzi-preview-create} +2 -2
  28. data/man/uffizzi-preview-create.html +128 -0
  29. data/man/{uffizzi-create.ronn → uffizzi-preview-create.ronn} +1 -1
  30. data/man/{uffizzi-delete → uffizzi-preview-delete} +2 -2
  31. data/man/uffizzi-preview-delete.html +115 -0
  32. data/man/{uffizzi-delete.ronn → uffizzi-preview-delete.ronn} +1 -1
  33. data/man/{uffizzi-describe → uffizzi-preview-describe} +2 -2
  34. data/man/uffizzi-preview-describe.html +116 -0
  35. data/man/{uffizzi-describe.ronn → uffizzi-preview-describe.ronn} +1 -1
  36. data/man/{uffizzi-events → uffizzi-preview-events} +22 -15
  37. data/man/uffizzi-preview-events.html +110 -0
  38. data/man/{uffizzi-events.ronn → uffizzi-preview-events.ronn} +7 -8
  39. data/man/{uffizzi-list → uffizzi-preview-list} +2 -2
  40. data/man/uffizzi-preview-list.html +110 -0
  41. data/man/{uffizzi-list.ronn → uffizzi-preview-list.ronn} +1 -1
  42. data/man/uffizzi-preview-service-list +38 -0
  43. data/man/uffizzi-preview-service-list.ronn +29 -0
  44. data/man/uffizzi-preview-service-logs +57 -0
  45. data/man/uffizzi-preview-service-logs.ronn +47 -0
  46. data/man/uffizzi-preview.html +120 -0
  47. data/man/uffizzi-preview.ronn +1 -1
  48. data/man/uffizzi-preview_service_logs +57 -0
  49. data/man/uffizzi-preview_service_logs.html +142 -0
  50. data/man/uffizzi-preview_service_logs.ronn +49 -0
  51. data/man/uffizzi-project +47 -0
  52. data/man/uffizzi-project-compose +40 -0
  53. data/man/uffizzi-project-compose-describe +37 -0
  54. data/man/uffizzi-project-compose-describe.html +118 -0
  55. data/man/uffizzi-project-compose-describe.ronn +29 -0
  56. data/man/uffizzi-project-compose-set +66 -0
  57. data/man/uffizzi-project-compose-set.html +149 -0
  58. data/man/uffizzi-project-compose-set.ronn +57 -0
  59. data/man/uffizzi-project-compose-unset +35 -0
  60. data/man/uffizzi-project-compose-unset.html +116 -0
  61. data/man/uffizzi-project-compose-unset.ronn +27 -0
  62. data/man/uffizzi-project-compose.html +123 -0
  63. data/man/uffizzi-project-compose.ronn +34 -0
  64. data/man/uffizzi-project-secret +37 -0
  65. data/man/uffizzi-project-secret-create +29 -0
  66. data/man/uffizzi-project-secret-create.html +110 -0
  67. data/man/uffizzi-project-secret-create.ronn +21 -0
  68. data/man/uffizzi-project-secret-delete +29 -0
  69. data/man/uffizzi-project-secret-delete.html +110 -0
  70. data/man/uffizzi-project-secret-delete.ronn +21 -0
  71. data/man/uffizzi-project-secret-list +28 -0
  72. data/man/uffizzi-project-secret-list.html +110 -0
  73. data/man/uffizzi-project-secret-list.ronn +20 -0
  74. data/man/uffizzi-project-secret.html +119 -0
  75. data/man/uffizzi-project-secret.ronn +30 -0
  76. data/man/uffizzi-project.html +128 -0
  77. data/man/uffizzi-project.ronn +41 -0
  78. data/man/uffizzi.html +132 -0
  79. data/man/uffizzi.ronn +43 -0
  80. metadata +89 -54
  81. data/.dockerignore +0 -9
  82. data/.rubocop.yml +0 -578
  83. data/CHANGELOG.md +0 -5
  84. data/CONTRIBUTING.md +0 -13
  85. data/Dockerfile +0 -46
  86. data/Gemfile +0 -5
  87. data/Gemfile.lock +0 -122
  88. data/Makefile +0 -31
  89. data/Rakefile +0 -21
  90. data/bin/console +0 -15
  91. data/bin/setup +0 -8
  92. data/docker-compose.yml +0 -29
  93. data/docker-entrypoint.sh +0 -20
  94. data/uffizzi.gemspec +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f4c103c385742d901959f98e01af795e472acae632cc162d74632be49b585fa
4
- data.tar.gz: b80618d6497a312b3b32605ae3778fcfce39e3aab4fad248daf8f3c7e52ff8cf
3
+ metadata.gz: beaa38102ec282e48c643ba8f6a8c80a331d6ded1760681a004341e2b671b5cf
4
+ data.tar.gz: c6517ea90506e72c11cb244f02f00760d5bb2afa1171f48fc9a997a8489165f0
5
5
  SHA512:
6
- metadata.gz: 00e878c19604b0a70668fc4eaacd46fdcc2c5bd63a8ff3c9ab0947bd7a3600e84968d09cc862d0e7257a1ab019c0eb8ec3ee5b5202a4f0ba6d9c03dbaa226c60
7
- data.tar.gz: 1d3613c7c3f4a613cc1e719243747e79d7b78e3941fe2f2da5b1a5e0a6a1d9a3aa5d96ce70a20925f236e3f3dc541ef82c17bd80fb04ee3153892a75e68097b5
6
+ metadata.gz: 2736a387fb65e9efe83fda0311f9f79bf4916bc828e9b6113bbf7e4e407256438e607af8f1f46dc6df1fa43423ba4728f6432396b60e06c24e16270024382f7a
7
+ data.tar.gz: 53b0f5951c72ebfba472e147e4397d311380b051baf41d3ca2c7e20f894a3ea417406f4ac8fbc3063902a79c7e11f1e39d5246aee0505377b01583d733056914
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
 
@@ -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)
@@ -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
@@ -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,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'thor'
4
-
5
3
  module Uffizzi
6
4
  module UI
7
5
  class Shell
6
+ attr_accessor :output_format
7
+
8
8
  def initialize
9
9
  @shell = Thor::Shell::Basic.new
10
10
  end
@@ -28,6 +28,31 @@ module Uffizzi
28
28
  def last_message
29
29
  @shell.send(:stdout).string.strip
30
30
  end
31
+
32
+ def disable_stdout
33
+ $stdout = StringIO.new
34
+ end
35
+
36
+ def output(data)
37
+ $stdout = IO.new(1, 'w')
38
+ json_format? ? output_in_json(data) : output_in_github_format(data)
39
+ end
40
+
41
+ private
42
+
43
+ def json_format?
44
+ output_format == 'json'
45
+ end
46
+
47
+ def output_in_json(data)
48
+ say(data.to_json)
49
+ end
50
+
51
+ def output_in_github_format(data)
52
+ data.each_key do |key|
53
+ say("::set-output name=#{key}::#{data[key]}")
54
+ end
55
+ end
31
56
  end
32
57
  end
33
58
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '0.3.7'
4
+ VERSION = '0.5.0'
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
data/man/uffizzi ADDED
@@ -0,0 +1,51 @@
1
+ .\" generated with Ronn-NG/v0.9.1
2
+ .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
+ .TH "UFFIZZI" "" "April 2022" ""
4
+ .SH "NAME"
5
+ \fBuffizzi\fR \- manage Uffizzi resources
6
+ .SH "SYNOPSIS"
7
+ .nf
8
+ uffizzi GROUP | COMMAND
9
+ .fi
10
+ .SH "DESCRIPTION"
11
+ .nf
12
+ The uffizzi CLI manages authentication, configuration, and
13
+ interaction with Uffizzi APIs\.
14
+
15
+ For more information on the uffizzi CLI, see:
16
+ https://docs\.uffizzi\.com/cli
17
+ .fi
18
+ .SH "GROUP"
19
+ .nf
20
+ GROUP is one of the following:
21
+
22
+ config
23
+ Configure the uffizzi CLI
24
+
25
+ connect
26
+ Grant a Uffizzi user account access to external services
27
+
28
+ preview
29
+ Manage Uffizzi previews and view logs
30
+
31
+ project
32
+ Manage Uffizzi project resources including compose files for
33
+ specifying preview configurations and secrets
34
+ .fi
35
+ .SH "COMMAND"
36
+ .nf
37
+ COMMAND is one of the following:
38
+
39
+ help
40
+ Show uffizzi documentation
41
+
42
+ login
43
+ Log in to a Uffizzi user account
44
+
45
+ logout
46
+ Log out of a Uffizzi user account
47
+
48
+ version
49
+ Print version information for uffizzi CLI
50
+ .fi
51
+