uffizzi-cli 1.0.5 → 2.0.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/config/uffizzi.rb +1 -0
  3. data/lib/uffizzi/auth_helper.rb +13 -5
  4. data/lib/uffizzi/cli/account.rb +122 -0
  5. data/lib/uffizzi/cli/cluster.rb +363 -0
  6. data/lib/uffizzi/cli/common.rb +2 -4
  7. data/lib/uffizzi/cli/config.rb +5 -4
  8. data/lib/uffizzi/cli/connect.rb +14 -8
  9. data/lib/uffizzi/cli/disconnect.rb +1 -1
  10. data/lib/uffizzi/cli/login.rb +130 -66
  11. data/lib/uffizzi/cli/login_by_identity_token.rb +11 -7
  12. data/lib/uffizzi/cli/preview/service.rb +1 -1
  13. data/lib/uffizzi/cli/preview.rb +33 -32
  14. data/lib/uffizzi/cli/project.rb +17 -9
  15. data/lib/uffizzi/cli.rb +46 -7
  16. data/lib/uffizzi/clients/api/api_client.rb +92 -2
  17. data/lib/uffizzi/clients/api/api_routes.rb +44 -0
  18. data/lib/uffizzi/clients/api/http_client.rb +19 -7
  19. data/lib/uffizzi/config_file.rb +15 -40
  20. data/lib/uffizzi/error.rb +15 -0
  21. data/lib/uffizzi/helpers/config_helper.rb +49 -0
  22. data/lib/uffizzi/helpers/file_helper.rb +25 -0
  23. data/lib/uffizzi/helpers/login_helper.rb +33 -0
  24. data/lib/uffizzi/helpers/project_helper.rb +19 -0
  25. data/lib/uffizzi/promt.rb +4 -0
  26. data/lib/uffizzi/response_helper.rb +33 -14
  27. data/lib/uffizzi/services/cluster_service.rb +59 -0
  28. data/lib/uffizzi/services/compose_file_service.rb +5 -4
  29. data/lib/uffizzi/services/env_variables_service.rb +1 -1
  30. data/lib/uffizzi/services/github_service.rb +21 -0
  31. data/lib/uffizzi/services/kubeconfig_service.rb +132 -0
  32. data/lib/uffizzi/services/preview_service.rb +52 -18
  33. data/lib/uffizzi/shell.rb +19 -16
  34. data/lib/uffizzi/token.rb +37 -0
  35. data/lib/uffizzi/version.rb +1 -1
  36. data/lib/uffizzi.rb +10 -0
  37. data/man/uffizzi +7 -5
  38. data/man/uffizzi-account +29 -0
  39. data/man/uffizzi-account-list +26 -0
  40. data/man/uffizzi-account-list.html +103 -0
  41. data/man/uffizzi-account-list.ronn +19 -0
  42. data/man/uffizzi-account-set-default +29 -0
  43. data/man/uffizzi-account-set-default.html +105 -0
  44. data/man/uffizzi-account-set-default.ronn +22 -0
  45. data/man/uffizzi-account.html +106 -0
  46. data/man/uffizzi-account.ronn +23 -0
  47. data/man/uffizzi-cluster +37 -0
  48. data/man/uffizzi-cluster-create +49 -0
  49. data/man/uffizzi-cluster-create.ronn +41 -0
  50. data/man/uffizzi-cluster-delete +32 -0
  51. data/man/uffizzi-cluster-delete.ronn +24 -0
  52. data/man/uffizzi-cluster-describe +39 -0
  53. data/man/uffizzi-cluster-describe.ronn +30 -0
  54. data/man/uffizzi-cluster-list +34 -0
  55. data/man/uffizzi-cluster-list.ronn +26 -0
  56. data/man/uffizzi-cluster-update-kubeconfig +37 -0
  57. data/man/uffizzi-cluster-update-kubeconfig.ronn +29 -0
  58. data/man/uffizzi-cluster.ronn +32 -0
  59. data/man/uffizzi-compose +39 -0
  60. data/man/uffizzi-compose-create +67 -0
  61. data/man/uffizzi-compose-create.ronn +57 -0
  62. data/man/uffizzi-compose-delete +38 -0
  63. data/man/uffizzi-compose-delete.ronn +29 -0
  64. data/man/uffizzi-compose-describe +38 -0
  65. data/man/uffizzi-compose-describe.ronn +29 -0
  66. data/man/uffizzi-compose-events +38 -0
  67. data/man/uffizzi-compose-events.ronn +29 -0
  68. data/man/uffizzi-compose-list +58 -0
  69. data/man/uffizzi-compose-list.ronn +49 -0
  70. data/man/uffizzi-compose-service-list +42 -0
  71. data/man/uffizzi-compose-service-list.ronn +32 -0
  72. data/man/uffizzi-compose-service-logs +59 -0
  73. data/man/uffizzi-compose-service-logs.ronn +48 -0
  74. data/man/uffizzi-compose-update +61 -0
  75. data/man/uffizzi-compose-update.ronn +51 -0
  76. data/man/uffizzi-compose.ronn +33 -0
  77. data/man/uffizzi-compose_service_logs +59 -0
  78. data/man/uffizzi-compose_service_logs.ronn +50 -0
  79. data/man/uffizzi-config +2 -2
  80. data/man/uffizzi-config.ronn +1 -1
  81. data/man/uffizzi-connect +2 -4
  82. data/man/uffizzi-connect-acr +2 -2
  83. data/man/uffizzi-connect-acr.ronn +1 -1
  84. data/man/uffizzi-connect-docker-hub +2 -2
  85. data/man/uffizzi-connect-docker-hub.ronn +1 -1
  86. data/man/uffizzi-connect-docker-registry +2 -2
  87. data/man/uffizzi-connect-docker-registry.ronn +1 -1
  88. data/man/uffizzi-connect-ecr +2 -2
  89. data/man/uffizzi-connect-ecr.ronn +1 -1
  90. data/man/uffizzi-connect-gcr +2 -2
  91. data/man/uffizzi-connect-gcr.ronn +1 -1
  92. data/man/uffizzi-connect-ghcr +2 -2
  93. data/man/uffizzi-connect-ghcr.ronn +1 -1
  94. data/man/uffizzi-connect.ronn +2 -2
  95. data/man/uffizzi-disconnect +2 -2
  96. data/man/uffizzi-disconnect.ronn +1 -1
  97. data/man/uffizzi-login +7 -3
  98. data/man/uffizzi-login-by-identity-token +3 -3
  99. data/man/uffizzi-login-by-identity-token.ronn +2 -2
  100. data/man/uffizzi-login.html +113 -0
  101. data/man/uffizzi-login.ronn +6 -2
  102. data/man/uffizzi-logout +2 -2
  103. data/man/uffizzi-logout.ronn +1 -1
  104. data/man/uffizzi-preview +9 -9
  105. data/man/uffizzi-preview-create +22 -20
  106. data/man/uffizzi-preview-create.ronn +28 -26
  107. data/man/uffizzi-preview-delete +11 -10
  108. data/man/uffizzi-preview-delete.ronn +12 -11
  109. data/man/uffizzi-preview-describe +10 -10
  110. data/man/uffizzi-preview-describe.ronn +11 -11
  111. data/man/uffizzi-preview-events +12 -11
  112. data/man/uffizzi-preview-events.ronn +13 -12
  113. data/man/uffizzi-preview-list +19 -18
  114. data/man/uffizzi-preview-list.ronn +21 -20
  115. data/man/uffizzi-preview-service-list +16 -12
  116. data/man/uffizzi-preview-service-list.ronn +16 -13
  117. data/man/uffizzi-preview-service-logs +14 -12
  118. data/man/uffizzi-preview-service-logs.ronn +18 -17
  119. data/man/uffizzi-preview-update +19 -18
  120. data/man/uffizzi-preview-update.ronn +21 -20
  121. data/man/uffizzi-preview.ronn +10 -10
  122. data/man/uffizzi-preview_service_logs +14 -12
  123. data/man/uffizzi-preview_service_logs.ronn +18 -17
  124. data/man/uffizzi-project +3 -3
  125. data/man/uffizzi-project-compose +2 -2
  126. data/man/uffizzi-project-compose-describe +2 -2
  127. data/man/uffizzi-project-compose-describe.ronn +1 -1
  128. data/man/uffizzi-project-compose-set +2 -2
  129. data/man/uffizzi-project-compose-set.ronn +1 -1
  130. data/man/uffizzi-project-compose-unset +2 -2
  131. data/man/uffizzi-project-compose-unset.ronn +1 -1
  132. data/man/uffizzi-project-compose.ronn +1 -1
  133. data/man/uffizzi-project-create +2 -2
  134. data/man/uffizzi-project-create.ronn +1 -1
  135. data/man/uffizzi-project-delete +2 -2
  136. data/man/uffizzi-project-delete.ronn +1 -1
  137. data/man/uffizzi-project-describe +3 -3
  138. data/man/uffizzi-project-describe.ronn +1 -1
  139. data/man/uffizzi-project-preview-describe +37 -0
  140. data/man/uffizzi-project-preview-describe.ronn +29 -0
  141. data/man/uffizzi-project-preview-set +66 -0
  142. data/man/uffizzi-project-preview-set.ronn +57 -0
  143. data/man/uffizzi-project-secret +2 -2
  144. data/man/uffizzi-project-secret-create +2 -2
  145. data/man/uffizzi-project-secret-create.ronn +1 -1
  146. data/man/uffizzi-project-secret-delete +2 -2
  147. data/man/uffizzi-project-secret-delete.ronn +1 -1
  148. data/man/uffizzi-project-secret-list +2 -2
  149. data/man/uffizzi-project-secret-list.ronn +1 -1
  150. data/man/uffizzi-project-secret.ronn +1 -1
  151. data/man/uffizzi-project-set-default +2 -2
  152. data/man/uffizzi-project-set-default.ronn +1 -1
  153. data/man/uffizzi-project.html +124 -0
  154. data/man/uffizzi-project.ronn +2 -2
  155. data/man/uffizzi.ronn +12 -10
  156. metadata +134 -22
@@ -3,7 +3,11 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/response_helper'
5
5
  require 'uffizzi/helpers/project_helper'
6
+ require 'uffizzi/helpers/login_helper'
7
+ require 'uffizzi/helpers/config_helper'
6
8
  require 'uffizzi/clients/api/api_client'
9
+ require 'launchy'
10
+ require 'securerandom'
7
11
  require 'tty-prompt'
8
12
 
9
13
  module Uffizzi
@@ -12,104 +16,146 @@ module Uffizzi
12
16
 
13
17
  def initialize(options)
14
18
  @options = options
19
+ @server = Uffizzi::LoginHelper.set_server(@options)
15
20
  end
16
21
 
17
22
  def run
18
- Uffizzi.ui.say('Login to Uffizzi server.')
19
- server = set_server
23
+ AuthHelper.sign_out if AuthHelper.signed_in?
24
+ return perform_email_login if @options[:email]
25
+
26
+ perform_browser_login
27
+ end
20
28
 
21
- username = set_username
22
- password = set_password
23
- params = prepare_request_params(username, password)
24
- response = create_session(server, params)
29
+ private
30
+
31
+ def perform_email_login
32
+ Uffizzi.ui.say('Login to Uffizzi server.')
33
+ username = Uffizzi::LoginHelper.set_username(@options)
34
+ password = Uffizzi::LoginHelper.set_password
35
+ params = Uffizzi::LoginHelper.prepare_request_params(username, password)
36
+ response = create_session(@server, params)
25
37
 
26
38
  if ResponseHelper.created?(response)
27
- handle_succeed_response(response, server, username)
39
+ handle_succeed_response(response, username)
28
40
  else
29
41
  ResponseHelper.handle_failed_response(response)
30
42
  end
31
43
  end
32
44
 
33
- private
45
+ def perform_browser_login
46
+ session_id = SecureRandom.uuid
47
+ response = create_access_token(@server, session_id)
48
+ return handle_failed_response(response) unless ResponseHelper.created?(response)
34
49
 
35
- def set_server
36
- config_server = ConfigFile.exists? ? read_option_from_config(:server) : nil
37
- server_address = (@options[:server] || config_server || Uffizzi.ui.ask('Server:')).sub(/\/+$/, '')
38
- server_address.start_with?('http:', 'https:') ? server_address : "https://#{server_address}"
39
- end
50
+ url = browser_sign_in_url(@server, session_id)
51
+ open_browser(url)
40
52
 
41
- def set_username
42
- config_username = ConfigFile.exists? ? read_option_from_config(:username) : nil
43
- @options[:username] || config_username || Uffizzi.ui.ask('Username:')
44
- end
53
+ loop do
54
+ response = get_access_token(@server, session_id)
45
55
 
46
- def set_password
47
- ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password:', echo: false)
56
+ if ResponseHelper.ok?(response)
57
+ break handle_token_success(response)
58
+ elsif ResponseHelper.unprocessable_entity?(response)
59
+ break Uffizzi.ui.say('The session has expired. Please try again.')
60
+ else
61
+ sleep(3)
62
+ end
63
+ end
48
64
  end
49
65
 
50
- def read_option_from_config(option)
51
- ConfigFile.option_has_value?(option) ? ConfigFile.read_option(option) : nil
52
- end
66
+ def handle_token_success(response)
67
+ ConfigFile.write_option(:server, @server)
68
+ token = response[:body][:access_token]
69
+ Uffizzi::Token.delete
70
+ Uffizzi::Token.write(token)
71
+ Uffizzi.ui.say('Login successfull')
53
72
 
54
- def prepare_request_params(username, password)
55
- {
56
- user: {
57
- email: username,
58
- password: password,
59
- },
60
- }
73
+ set_current_account_and_project
61
74
  end
62
75
 
63
- def handle_succeed_response(response, server, username)
64
- # TODO Choose a personal account
65
- account = response[:body][:user][:accounts].first
66
- return Uffizzi.ui.say('No account related to this email') unless account_valid?(account)
76
+ def open_browser(url)
77
+ Launchy.open(url) do |_exception|
78
+ Uffizzi.ui.say('Login to Uffizzi server.')
79
+ Uffizzi.ui.say(url)
80
+ end
81
+ end
67
82
 
68
- ConfigFile.write_option(:server, server)
83
+ def handle_succeed_response(response, username)
84
+ ConfigFile.write_option(:server, @server)
69
85
  ConfigFile.write_option(:username, username)
70
86
  ConfigFile.write_option(:cookie, response[:headers])
71
- ConfigFile.write_option(:account_id, account[:id])
72
-
73
87
  Uffizzi.ui.say('Login successfull')
74
88
 
75
- default_project = ConfigFile.read_option(:project)
76
- return unless default_project
89
+ if ENV.fetch('CI_PIPELINE_RUN', false)
90
+ account = response[:body][:user][:default_account]
91
+ return ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(account[:id]))
92
+ end
77
93
 
78
- check_default_project(default_project, server)
94
+ set_current_account_and_project
79
95
  end
80
96
 
81
- def account_valid?(account)
82
- account[:state] == 'active'
97
+ def set_current_account_and_project
98
+ current_account_id = ConfigFile.read_option(:account, :id)
99
+ current_project_slug = ConfigFile.read_option(:project)
100
+
101
+ unless current_account_id
102
+ account_id = set_account
103
+ return set_project(account_id)
104
+ end
105
+
106
+ return if current_project_slug && project_exists?(current_account_id, current_project_slug)
107
+
108
+ set_project(account_id)
83
109
  end
84
110
 
85
- def check_default_project(default_project, server)
86
- check_project_response = fetch_projects(server)
111
+ def project_exists?(account_id, project_slug)
112
+ check_project_response = fetch_account_projects(@server, account_id)
87
113
  return ResponseHelper.handle_failed_response(check_project_response) unless ResponseHelper.ok?(check_project_response)
88
114
 
89
115
  projects = check_project_response[:body][:projects]
90
116
  slugs = projects.map { |project| project[:slug] }
91
- return if slugs.include?(default_project)
92
117
 
93
- question = "Project '#{default_project}' does not exist. Select one of the following projects or create a new project:"
118
+ slugs.include?(project_slug)
119
+ end
120
+
121
+ def set_account
122
+ accounts_response = fetch_accounts(@server)
123
+ accounts = accounts_response[:body][:accounts]
124
+ if accounts.length == 1
125
+ current_account = accounts.first
126
+ ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(current_account[:id], current_account[:name]))
127
+ return current_account[:id]
128
+ end
129
+ question = 'Select an account:'
130
+ choices = accounts.map do |account|
131
+ { name: account[:name], value: account[:id] }
132
+ end
133
+ account_id = Uffizzi.prompt.select(question, choices)
134
+ account_name = accounts.detect { |account| account[:id] == account_id }[:name]
135
+
136
+ ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(account_id, account_name))
137
+
138
+ account_id
139
+ end
140
+
141
+ def set_project(account_id)
142
+ projects_response = fetch_account_projects(@server, account_id)
143
+ projects = projects_response[:body][:projects]
94
144
  choices = projects.map do |project|
95
145
  { name: project[:name], value: project[:slug] }
96
146
  end
97
147
  all_choices = choices + [{ name: 'Create a new project', value: nil }]
148
+ question = 'Select a project or create a new project:'
98
149
  answer = Uffizzi.prompt.select(question, all_choices)
99
- return create_new_project(server) unless answer
150
+ return create_new_project unless answer
100
151
 
101
- account_id = projects.detect { |project| project[:slug] == answer }[:account_id]
102
152
  ConfigFile.write_option(:project, answer)
103
- ConfigFile.write_option(:account_id, account_id)
104
153
  end
105
154
 
106
- def create_new_project(server)
107
- project_name = Uffizzi.prompt.ask('Project name: ', required: true)
108
- generated_slug = Uffizzi::ProjectHelper.generate_slug(project_name)
109
- project_slug = Uffizzi.prompt.ask('Project slug: ', default: generated_slug)
110
- raise Uffizzi::Error.new('Slug must not content spaces or special characters') unless project_slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)
111
-
112
- project_description = Uffizzi.prompt.ask('Project desciption: ')
155
+ def create_new_project(prev_params = {})
156
+ project_name = Uffizzi.prompt.ask('Project name: ', required: true, default: prev_params.fetch(:name, nil))
157
+ project_slug = ask_project_slug(project_name, prev_params.fetch(:slug, nil))
158
+ project_description = Uffizzi.prompt.ask('Project desciption: ', default: prev_params.fetch(:description, nil))
113
159
 
114
160
  params = {
115
161
  project: {
@@ -119,31 +165,49 @@ module Uffizzi
119
165
  },
120
166
  }
121
167
 
122
- account_id = ConfigFile.read_option(:account_id)
123
- response = create_project(server, account_id, params)
168
+ account_id = ConfigFile.read_option(:account, :id)
169
+ response = create_project(@server, account_id, params)
124
170
 
125
171
  if ResponseHelper.created?(response)
126
172
  handle_create_project_succeess(response)
127
173
  else
128
- handle_create_project_failed(response)
174
+ handle_create_project_failed(response, params[:project])
129
175
  end
130
176
  end
131
177
 
132
- def handle_create_project_failed(response)
133
- name_error = response[:body][:errors][:name].first
134
- name_already_exists = name_error && name_error.first == 'Name already exists'
135
- message = "Project with name #{project_name} already exists. " \
136
- 'Please run $ uffizzi config to set it as a default project'
137
- raise Uffizzi::Error.new(message) if name_already_exists
178
+ def ask_project_slug(project_name, prev_slug = nil)
179
+ generated_slug = Uffizzi::ProjectHelper.generate_slug(project_name)
180
+ default_slug = prev_slug || generated_slug
181
+ project_slug = Uffizzi.prompt.ask('Project slug: ', default: default_slug)
182
+ return project_slug if project_slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)
183
+
184
+ question = 'Slug must not content spaces or special characters. Do you want to a different project slug?'
185
+ answer = Uffizzi.prompt.yes?(question)
186
+ return ask_project_slug(project_name) if answer
187
+
188
+ raise Uffizzi::Error.new('Project creation aborted')
189
+ end
190
+
191
+ def handle_create_project_failed(response, project_params)
192
+ errors = [:name, :slug].map { |error_key| response.dig(:body, :errors, error_key).to_a.first }.compact
193
+
194
+ if errors.blank?
195
+ return ResponseHelper.handle_failed_response(response)
196
+ end
197
+
198
+ Uffizzi.ui.say(errors.join("\n"))
199
+ question = 'Do you want to try different project params?'
200
+ answer = Uffizzi.prompt.yes?(question)
201
+
202
+ return create_new_project(project_params) if answer
138
203
 
139
- ResponseHelper.handle_failed_response(response)
204
+ raise Uffizzi::Error.new("Project creation aborted. You can run 'uffizzi config' to set project as a default")
140
205
  end
141
206
 
142
207
  def handle_create_project_succeess(response)
143
208
  project = response[:body][:project]
144
209
 
145
210
  ConfigFile.write_option(:project, project[:slug])
146
- ConfigFile.write_option(:account_id, project[:account_id])
147
211
 
148
212
  Uffizzi.ui.say("Project #{project[:name]} was successfully created")
149
213
  end
@@ -3,6 +3,7 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/response_helper'
5
5
  require 'uffizzi/clients/api/api_client'
6
+ require 'uffizzi/helpers/config_helper'
6
7
 
7
8
  module Uffizzi
8
9
  class Cli::LoginByIdentityToken
@@ -13,13 +14,14 @@ module Uffizzi
13
14
  end
14
15
 
15
16
  def run
16
- token = @options[:token]
17
+ oidc_token = @options[:oidc_token]
18
+ github_access_token = @options[:access_token]
17
19
  server = @options[:server]
18
- params = prepare_request_params(token)
20
+ params = prepare_request_params(oidc_token, github_access_token)
19
21
  response = create_ci_session(server, params)
20
22
 
21
23
  if ResponseHelper.created?(response)
22
- handle_succeed_response(response, server)
24
+ handle_succeed_response(response, server, oidc_token)
23
25
  else
24
26
  ResponseHelper.handle_failed_response(response)
25
27
  end
@@ -27,19 +29,21 @@ module Uffizzi
27
29
 
28
30
  private
29
31
 
30
- def prepare_request_params(token)
32
+ def prepare_request_params(oidc_token, github_access_token)
31
33
  {
32
34
  user: {
33
- token: token,
35
+ token: oidc_token,
36
+ github_access_token: github_access_token,
34
37
  },
35
38
  }
36
39
  end
37
40
 
38
- def handle_succeed_response(response, server)
41
+ def handle_succeed_response(response, server, oidc_token)
39
42
  ConfigFile.write_option(:server, server)
40
43
  ConfigFile.write_option(:cookie, response[:headers])
41
- ConfigFile.write_option(:account_id, response[:body][:account_id])
44
+ ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(response[:body][:account_id]))
42
45
  ConfigFile.write_option(:project, response[:body][:project_slug])
46
+ ConfigFile.write_option(:oidc_token, oidc_token)
43
47
 
44
48
  Uffizzi.ui.say('Successful Login by Identity Token')
45
49
  end
@@ -26,7 +26,7 @@ module Uffizzi
26
26
  end
27
27
  end
28
28
 
29
- desc 'list [DEPLOYMENT_ID]', 'List the container services of a given preview'
29
+ desc 'list [DEPLOYMENT_ID]', 'List the container services of a given compose environment (preview)'
30
30
  def list(deployment_name)
31
31
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
32
32
  return Uffizzi.ui.say('This command needs project to be set in config file') unless CommandService.project_set?(options)
@@ -4,47 +4,49 @@ require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/services/preview_service'
6
6
  require 'uffizzi/services/command_service'
7
+ require 'uffizzi/services/github_service'
7
8
 
8
9
  module Uffizzi
9
10
  class Cli::Preview < Thor
10
11
  include ApiClient
11
12
 
12
- desc 'service', 'Show the preview services info'
13
+ desc 'service', 'Show the compose environment (preview) services info'
13
14
  require_relative 'preview/service'
14
15
  subcommand 'service', Uffizzi::Cli::Preview::Service
15
16
 
16
- desc 'list', 'List all previews'
17
+ desc 'list', 'List all compose environments (previews)'
17
18
  method_option :filter, required: false, type: :string, aliases: '-f'
18
19
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'pretty-json']
19
20
  def list
20
21
  run('list')
21
22
  end
22
23
 
23
- desc 'create [COMPOSE_FILE]', 'Create a preview'
24
+ desc 'create [COMPOSE_FILE]', 'Create a compose environment (preview)'
24
25
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
25
26
  method_option :"set-labels", required: false, type: :string, aliases: '-s'
27
+ method_option :"creation-source", required: false, type: :string
26
28
  def create(file_path = nil)
27
29
  run('create', file_path: file_path)
28
30
  end
29
31
 
30
- desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a preview'
32
+ desc 'update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a compose environment (preview)'
31
33
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
32
34
  method_option :"set-labels", required: false, type: :string, aliases: '-s'
33
35
  def update(deployment_name, file_path)
34
36
  run('update', deployment_name: deployment_name, file_path: file_path)
35
37
  end
36
38
 
37
- desc 'delete [DEPLOYMENT_ID]', 'Delete a preview'
39
+ desc 'delete [DEPLOYMENT_ID]', 'Delete a compose environment (preview)'
38
40
  def delete(deployment_name)
39
41
  run('delete', deployment_name: deployment_name)
40
42
  end
41
43
 
42
- desc 'describe [DEPLOYMENT_ID]', 'Display details of a preview'
44
+ desc 'describe [DEPLOYMENT_ID]', 'Display details of a compose environment (preview)'
43
45
  def describe(deployment_name)
44
46
  run('describe', deployment_name: deployment_name)
45
47
  end
46
48
 
47
- desc 'events [DEPLOYMENT_ID]', 'Show the deployment event logs for a preview'
49
+ desc 'events [DEPLOYMENT_ID]', 'Show the deployment event logs for a compose environment (preview)'
48
50
  def events(deployment_name)
49
51
  run('events', deployment_name: deployment_name)
50
52
  end
@@ -62,7 +64,7 @@ module Uffizzi
62
64
  when 'list'
63
65
  handle_list_command(project_slug, options[:filter])
64
66
  when 'create'
65
- handle_create_command(file_path, project_slug, options[:"set-labels"])
67
+ handle_create_command(file_path, project_slug, options[:"set-labels"], options[:"creation-source"])
66
68
  when 'update'
67
69
  handle_update_command(deployment_name, file_path, project_slug, options[:"set-labels"])
68
70
  when 'delete'
@@ -85,10 +87,9 @@ module Uffizzi
85
87
  end
86
88
  end
87
89
 
88
- def handle_create_command(file_path, project_slug, labels)
89
- Uffizzi.ui.disable_stdout unless options[:output].nil?
90
-
91
- params = prepare_params(file_path, labels)
90
+ def handle_create_command(file_path, project_slug, labels, creation_source)
91
+ Uffizzi.ui.disable_stdout if Uffizzi.ui.output_format
92
+ params = prepare_params(file_path, labels, creation_source)
92
93
 
93
94
  response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
94
95
 
@@ -98,17 +99,18 @@ module Uffizzi
98
99
 
99
100
  deployment = response[:body][:deployment]
100
101
  Uffizzi.ui.say("Preview with ID deployment-#{deployment[:id]} was created.")
102
+ deployment_data = build_deployment_data(deployment)
103
+ Uffizzi.ui.say("Deployment details url: #{deployment_data[:containers_uri]}")
101
104
 
102
- success = PreviewService.run_containers_deploy(project_slug, deployment)
103
-
104
- display_deployment_data(deployment, success)
105
+ PreviewService.run_containers_deploy(project_slug, deployment)
106
+ handle_result(deployment_data)
105
107
  rescue SystemExit, Interrupt, SocketError
106
108
  deployment_id = response[:body][:deployment][:id]
107
109
  handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
108
110
  end
109
111
 
110
112
  def handle_update_command(deployment_name, file_path, project_slug, labels)
111
- Uffizzi.ui.disable_stdout unless options[:output].nil?
113
+ Uffizzi.ui.disable_stdout if Uffizzi.ui.output_format
112
114
  deployment_id = PreviewService.read_deployment_id(deployment_name)
113
115
 
114
116
  raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
@@ -122,10 +124,11 @@ module Uffizzi
122
124
 
123
125
  deployment = response[:body][:deployment]
124
126
  Uffizzi.ui.say("Preview with ID deployment-#{deployment_id} was updated.")
127
+ deployment_data = build_deployment_data(deployment)
128
+ Uffizzi.ui.say("Deployment details url: #{deployment_data[:containers_uri]}")
125
129
 
126
- success = PreviewService.run_containers_deploy(project_slug, deployment)
127
-
128
- display_deployment_data(deployment, success)
130
+ PreviewService.run_containers_deploy(project_slug, deployment)
131
+ handle_result(deployment_data)
129
132
  rescue SystemExit, Interrupt, SocketError
130
133
  deployment_id = response[:body][:deployment][:id]
131
134
  handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
@@ -215,10 +218,13 @@ module Uffizzi
215
218
  end
216
219
  end
217
220
 
218
- def prepare_params(file_path, labels)
221
+ def prepare_params(file_path, labels, creation_source = nil)
219
222
  compose_file_params = file_path.nil? ? {} : build_compose_file_params(file_path)
220
223
  metadata_params = labels.nil? ? {} : build_metadata_params(labels)
221
- compose_file_params.merge(metadata_params)
224
+ oidc_token = ConfigFile.read_option(:oidc_token)
225
+ extra_params = oidc_token.nil? ? {} : { token: oidc_token }
226
+ params = compose_file_params.merge(metadata_params)
227
+ params.merge(extra_params, { creation_source: creation_source })
222
228
  end
223
229
 
224
230
  def handle_preview_interruption(deployment_id, server, project_slug)
@@ -227,22 +233,16 @@ module Uffizzi
227
233
  preview_deletion_message = if ResponseHelper.no_content?(deletion_response)
228
234
  "The preview #{deployment_name} has been disabled."
229
235
  else
230
- "Couldn't disable the deployment #{deployment_name} - please disable maually."
236
+ "Couldn't disable the deployment #{deployment_name} - please disable manually."
231
237
  end
232
238
 
233
239
  raise Uffizzi::Error.new("The preview creation was interrupted. #{preview_deletion_message}")
234
240
  end
235
241
 
236
- def display_deployment_data(deployment, success)
237
- if Uffizzi.ui.output_format.nil?
238
- Uffizzi.ui.say('Done')
239
- preview_url = "https://#{deployment[:preview_url]}"
240
- Uffizzi.ui.say(preview_url) if success
241
- else
242
- deployment_data = build_deployment_data(deployment)
243
- Uffizzi.ui.enable_stdout
244
- Uffizzi.ui.say(deployment_data)
245
- end
242
+ def handle_result(deployment_data)
243
+ Uffizzi.ui.enable_stdout
244
+ Uffizzi.ui.say(deployment_data) if Uffizzi.ui.output_format
245
+ GithubService.write_to_github_env(deployment_data) if GithubService.github_actions_exists?
246
246
  end
247
247
 
248
248
  def build_deployment_data(deployment)
@@ -251,6 +251,7 @@ module Uffizzi
251
251
  {
252
252
  id: "deployment-#{deployment[:id]}",
253
253
  url: "https://#{deployment[:preview_url]}",
254
+ proxy_url: "https://#{deployment[:proxy_preview_url]}",
254
255
  containers_uri: "#{url_server}/projects/#{deployment[:project_id]}/deployments/#{deployment[:id]}/containers",
255
256
  }
256
257
  end
@@ -4,6 +4,7 @@ require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
6
  require 'uffizzi/helpers/project_helper'
7
+ require 'uffizzi/helpers/config_helper'
7
8
  require 'uffizzi/services/project_service'
8
9
 
9
10
  module Uffizzi
@@ -36,6 +37,7 @@ module Uffizzi
36
37
  end
37
38
 
38
39
  map('set-default' => :set_default)
40
+ map('set' => :set_default)
39
41
 
40
42
  method_option :name, required: true
41
43
  method_option :slug, default: ''
@@ -70,7 +72,7 @@ module Uffizzi
70
72
  end
71
73
 
72
74
  def handle_describe_command(project_slug)
73
- response = describe_project(ConfigFile.read_option(:server), project_slug)
75
+ response = fetch_project(ConfigFile.read_option(:server), project_slug)
74
76
 
75
77
  if ResponseHelper.ok?(response)
76
78
  handle_succeed_describe_response(response)
@@ -87,7 +89,8 @@ module Uffizzi
87
89
 
88
90
  def handle_list_command
89
91
  server = ConfigFile.read_option(:server)
90
- response = fetch_projects(server)
92
+ account_id = ConfigFile.read_option(:account, :id)
93
+ response = fetch_account_projects(server, account_id)
91
94
 
92
95
  if ResponseHelper.ok?(response)
93
96
  handle_list_success_response(response)
@@ -102,7 +105,8 @@ module Uffizzi
102
105
  raise Uffizzi::Error.new('Slug must not content spaces or special characters') unless slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)
103
106
 
104
107
  server = ConfigFile.read_option(:server)
105
- account_id = ConfigFile.read_option(:account_id)
108
+ account_id = ConfigFile.read_option(:account, :id)
109
+
106
110
  params = {
107
111
  name: name,
108
112
  description: options[:description],
@@ -130,14 +134,14 @@ module Uffizzi
130
134
 
131
135
  def handle_list_success_response(response)
132
136
  projects = response[:body][:projects]
133
- return Uffizzi.ui.say('No projects related to this email') if projects.empty?
137
+ return Uffizzi.ui.say('No projects found') if projects.empty?
134
138
 
135
139
  set_default_project(projects.first) if projects.size == 1
136
140
  print_projects(projects)
137
141
  end
138
142
 
139
143
  def handle_set_default_command(project_slug)
140
- response = describe_project(ConfigFile.read_option(:server), project_slug)
144
+ response = fetch_project(ConfigFile.read_option(:server), project_slug)
141
145
 
142
146
  if ResponseHelper.ok?(response)
143
147
  handle_succeed_set_default_response(response)
@@ -152,9 +156,9 @@ module Uffizzi
152
156
  end
153
157
 
154
158
  def handle_create_success_response(response)
155
- project_name = response[:body][:project][:name]
156
-
157
- Uffizzi.ui.say("Project #{project_name} was successfully created")
159
+ project = response[:body][:project]
160
+ ConfigFile.write_option(:project, project[:slug])
161
+ Uffizzi.ui.say("Project '#{project[:name]}' with slug '#{project[:slug]}' was successfully created")
158
162
  end
159
163
 
160
164
  def print_projects(projects)
@@ -166,7 +170,11 @@ module Uffizzi
166
170
 
167
171
  def set_default_project(project)
168
172
  ConfigFile.write_option(:project, project[:slug])
169
- ConfigFile.write_option(:account_id, project[:account_id])
173
+ account = project[:account]
174
+ return ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(account[:id], account[:name])) if account
175
+
176
+ # For core versions < core_v2.2.3
177
+ ConfigFile.write_option(:account, Uffizzi::ConfigHelper.account_config(project[:account_id]))
170
178
  end
171
179
  end
172
180
  end