uffizzi-cli 0.11.4 → 0.14.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e92bf221528510c670cb020826d6449a4c200dcdacb6b6c42cea9344f1aac12b
4
- data.tar.gz: d95b2e8069051b7450d099add663104da159756913ca977d303f673805d8d0cb
3
+ metadata.gz: a7a27f279e964f07491f920557722194d65c8a9259487a5a717707f6075d164b
4
+ data.tar.gz: d9825fe3425b0dde3dbe1e4528686100c6ca22f30aed4aa7a332cf991bbb6480
5
5
  SHA512:
6
- metadata.gz: a3da65fe42dd24ddca4c3c5fb7b15349e1daeef00689c421b0556d1d58eb34169de7c8bb4474ff1594fc5e526a1a5d8bd89124b649fb2606f10172440236613d
7
- data.tar.gz: f68cba8bbbf8591dfb5310606f7322b312171d1110587fd80969453fccaa82d2f31aab560731d962122e82524f7a4ac20283e5f2d2b8965b0e027bae370e3746
6
+ metadata.gz: 179a75d66bd89efc1ad9b3decf5ebc6c5526b2fe0fdd02e616940b4f12544505c956874a0649a99a2c5d1e14fce6e1dcda305a9028e08d8e9c2b8b5f63955fb5
7
+ data.tar.gz: a8d2637bef4250c33bb1cc8725556a2758384c9115938865e8acd70b92fce515ccd94b691913341c6b6f64a29f6d9ff34e99148fd62cacf8d6551d72a1222508
data/config/uffizzi.rb CHANGED
@@ -19,6 +19,7 @@ module Uffizzi
19
19
  google: 'UffizziCore::Credential::Google',
20
20
  amazon: 'UffizziCore::Credential::Amazon',
21
21
  github_registry: 'UffizziCore::Credential::GithubContainerRegistry',
22
+ docker_registry: 'UffizziCore::Credential::DockerRegistry',
22
23
  }
23
24
  config.default_server = 'app.uffizzi.com'
24
25
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'uffizzi'
4
+ require 'uffizzi/helpers/connect_helper'
4
5
 
5
6
  module Uffizzi
6
7
  class Cli::Connect < Thor
@@ -20,39 +21,76 @@ module Uffizzi
20
21
  desc 'docker-hub', 'Connect to Docker Hub (hub.docker.com)'
21
22
  method_option :skip_raise_existence_error, type: :boolean, default: false,
22
23
  desc: 'Skip raising an error within check the credential'
24
+ method_option :update_credential_if_exists, type: :boolean, default: false
25
+ method_option :username, type: :string, aliases: :u
26
+ method_option :password, type: :string, aliases: :p
23
27
  def docker_hub
24
28
  type = Uffizzi.configuration.credential_types[:dockerhub]
25
- check_credential_existence(type, 'docker-hub')
29
+ credential_exists = credential_exists?(type)
30
+ handle_existing_credential_options('docker-hub') if credential_exists
26
31
 
27
- username = ENV['DOCKERHUB_USERNAME'] || Uffizzi.ui.ask('Username: ')
28
- password = ENV['DOCKERHUB_PASSWORD'] || Uffizzi.ui.ask('Password: ', echo: false)
32
+ username, password = Uffizzi::ConnectHelper.get_docker_hub_data(options)
29
33
 
30
34
  params = {
31
35
  username: username,
32
36
  password: password,
33
- type: Uffizzi.configuration.credential_types[:dockerhub],
37
+ type: type,
34
38
  }
39
+ server = ConfigFile.read_option(:server)
40
+
41
+ response = if credential_exists
42
+ update_credential(server, params, type)
43
+ else
44
+ create_credential(server, params)
45
+ end
35
46
 
47
+ handle_result_for('Docker Hub', response)
48
+ end
49
+
50
+ desc 'docker-registry', 'Connect to any registry implementing the Docker Registry HTTP API protocol'
51
+ method_option :skip_raise_existence_error, type: :boolean, default: false,
52
+ desc: 'Skip raising an error within check the credential'
53
+ method_option :update_credential_if_exists, type: :boolean, default: false
54
+ method_option :registry, type: :string, aliases: :r
55
+ method_option :username, type: :string, aliases: :u
56
+ method_option :password, type: :string, aliases: :p
57
+ def docker_registry
58
+ type = Uffizzi.configuration.credential_types[:docker_registry]
59
+ credential_exists = credential_exists?(type)
60
+ handle_existing_credential_options('docker-registry') if credential_exists
61
+
62
+ registry_url, username, password = Uffizzi::ConnectHelper.get_docker_registry_data(options)
63
+
64
+ params = {
65
+ registry_url: prepare_registry_url(registry_url),
66
+ username: username,
67
+ password: password,
68
+ type: type,
69
+ }
36
70
  server = ConfigFile.read_option(:server)
37
- response = create_credential(server, params)
38
71
 
39
- if ResponseHelper.created?(response)
40
- print_success_message('DockerHub')
72
+ response = if credential_exists
73
+ update_credential(server, params, type)
41
74
  else
42
- ResponseHelper.handle_failed_response(response)
75
+ create_credential(server, params)
43
76
  end
77
+
78
+ handle_result_for('Docker Registry', response)
44
79
  end
45
80
 
46
81
  desc 'acr', 'Connect to Azure Container Registry (azurecr.io)'
47
82
  method_option :skip_raise_existence_error, type: :boolean, default: false,
48
83
  desc: 'Skip raising an error within check the credential'
84
+ method_option :update_credential_if_exists, type: :boolean, default: false
85
+ method_option :registry, type: :string, aliases: :r
86
+ method_option :username, type: :string, aliases: :u
87
+ method_option :password, type: :string, aliases: :p
49
88
  def acr
50
89
  type = Uffizzi.configuration.credential_types[:azure]
51
- check_credential_existence(type, 'acr')
90
+ credential_exists = credential_exists?(type)
91
+ handle_existing_credential_options('acr') if credential_exists
52
92
 
53
- registry_url = ENV['ACR_REGISTRY_URL'] || Uffizzi.ui.ask('Registry Domain: ')
54
- username = ENV['ACR_USERNAME'] || Uffizzi.ui.ask('Docker ID: ')
55
- password = ENV['ACR_PASSWORD'] || Uffizzi.ui.ask('Password/Access Token: ', echo: false)
93
+ registry_url, username, password = Uffizzi::ConnectHelper.get_acr_data(options)
56
94
 
57
95
  params = {
58
96
  username: username,
@@ -60,51 +98,56 @@ module Uffizzi
60
98
  registry_url: prepare_registry_url(registry_url),
61
99
  type: type,
62
100
  }
63
-
64
101
  server = ConfigFile.read_option(:server)
65
- response = create_credential(server, params)
66
102
 
67
- if ResponseHelper.created?(response)
68
- print_success_message('ACR')
103
+ response = if credential_exists
104
+ update_credential(server, params, type)
69
105
  else
70
- ResponseHelper.handle_failed_response(response)
106
+ create_credential(server, params)
71
107
  end
108
+
109
+ handle_result_for('ACR', response)
72
110
  end
73
111
 
74
112
  desc 'ecr', 'Connect to Amazon Elastic Container Registry'
75
113
  method_option :skip_raise_existence_error, type: :boolean, default: false,
76
114
  desc: 'Skip raising an error within check the credential'
115
+ method_option :update_credential_if_exists, type: :boolean, default: false
116
+ method_option :registry, type: :string, aliases: :r
117
+ method_option :id, type: :string
118
+ method_option :secret, type: :string, aliases: :s
77
119
  def ecr
78
120
  type = Uffizzi.configuration.credential_types[:amazon]
79
- check_credential_existence(type, 'ecr')
121
+ credential_exists = credential_exists?(type)
122
+ handle_existing_credential_options('ecr') if credential_exists
80
123
 
81
- registry_url = ENV['AWS_REGISTRY_URL'] || Uffizzi.ui.ask('Registry Domain: ')
82
- access_key = ENV['AWS_ACCESS_KEY_ID'] || Uffizzi.ui.ask('Access key ID: ')
83
- secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || Uffizzi.ui.ask('Secret access key: ', echo: false)
124
+ registry_url, access_key_id, secret_access_key = Uffizzi::ConnectHelper.get_ecr_data(options)
84
125
 
85
126
  params = {
86
- username: access_key,
127
+ username: access_key_id,
87
128
  password: secret_access_key,
88
129
  registry_url: prepare_registry_url(registry_url),
89
130
  type: type,
90
131
  }
91
-
92
132
  server = ConfigFile.read_option(:server)
93
- response = create_credential(server, params)
94
133
 
95
- if ResponseHelper.created?(response)
96
- print_success_message('ECR')
134
+ response = if credential_exists
135
+ update_credential(server, params, type)
97
136
  else
98
- ResponseHelper.handle_failed_response(response)
137
+ create_credential(server, params)
99
138
  end
139
+
140
+ handle_result_for('ECR', response)
100
141
  end
101
142
 
102
143
  desc 'gcr', 'Connect to Google Container Registry (gcr.io)'
103
144
  method_option :skip_raise_existence_error, type: :boolean, default: false,
104
145
  desc: 'Skip raising an error within check the credential'
146
+ method_option :update_credential_if_exists, type: :boolean, default: false
105
147
  def gcr(credential_file_path = nil)
106
148
  type = Uffizzi.configuration.credential_types[:google]
107
- check_credential_existence(type, 'gcr')
149
+ credential_exists = credential_exists?(type)
150
+ handle_existing_credential_options('gcr') if credential_exists
108
151
 
109
152
  credential_content = google_service_account_content(credential_file_path)
110
153
 
@@ -112,71 +155,88 @@ module Uffizzi
112
155
  password: credential_content,
113
156
  type: type,
114
157
  }
115
-
116
158
  server = ConfigFile.read_option(:server)
117
- response = create_credential(server, params)
118
159
 
119
- if ResponseHelper.created?(response)
120
- print_success_message('GCR')
160
+ response = if credential_exists
161
+ update_credential(server, params, type)
121
162
  else
122
- ResponseHelper.handle_failed_response(response)
163
+ create_credential(server, params)
123
164
  end
165
+
166
+ handle_result_for('GCR', response)
124
167
  end
125
168
 
126
169
  desc 'ghcr', 'Connect to GitHub Container Registry (ghcr.io)'
127
170
  method_option :skip_raise_existence_error, type: :boolean, default: false,
128
171
  desc: 'Skip raising an error within check the credential'
172
+ method_option :update_credential_if_exists, type: :boolean, default: false
129
173
  method_option :username, type: :string, aliases: :u
130
174
  method_option :token, type: :string, aliases: :t
131
175
  def ghcr
132
176
  type = Uffizzi.configuration.credential_types[:github_registry]
133
- check_credential_existence(type, 'ghcr')
177
+ credential_exists = credential_exists?(type)
178
+ handle_existing_credential_options('ghcr') if credential_exists
134
179
 
135
- username = options[:username] || ENV['GITHUB_USERNAME'] || Uffizzi.ui.ask('Github Username:')
136
- password = options[:token] || ENV['GITHUB_ACCESS_TOKEN'] || Uffizzi.ui.ask('Access Token:', echo: false)
180
+ username, password = Uffizzi::ConnectHelper.get_ghcr_data(options)
137
181
 
138
182
  params = {
139
183
  username: username,
140
184
  password: password,
141
185
  type: type,
142
186
  }
143
-
144
187
  server = ConfigFile.read_option(:server)
145
- response = create_credential(server, params)
146
188
 
147
- if ResponseHelper.created?(response)
148
- print_success_message('GHCR')
189
+ response = if credential_exists
190
+ update_credential(server, params, type)
149
191
  else
150
- ResponseHelper.handle_failed_response(response)
192
+ create_credential(server, params)
151
193
  end
194
+
195
+ handle_result_for('GHCR', response)
152
196
  end
153
197
 
154
198
  map 'list-credentials' => 'list_credentials'
155
199
  map 'docker-hub' => 'docker_hub'
200
+ map 'docker-registry' => 'docker_registry'
156
201
 
157
202
  private
158
203
 
204
+ def handle_result_for(credential_type, response)
205
+ if ResponseHelper.created?(response) || ResponseHelper.ok?(response)
206
+ print_success_message(credential_type)
207
+ else
208
+ ResponseHelper.handle_failed_response(response)
209
+ end
210
+ end
211
+
159
212
  def prepare_registry_url(registry_url)
160
213
  return registry_url if registry_url.match?(/^(?:http(s)?:\/\/)/)
161
214
 
162
215
  "https://#{registry_url}"
163
216
  end
164
217
 
165
- def print_success_message(connection_name)
166
- Uffizzi.ui.say("Successfully connected to #{connection_name}")
218
+ def print_success_message(credential_type)
219
+ Uffizzi.ui.say("Successfully connected to #{credential_type}.")
167
220
  end
168
221
 
169
- def check_credential_existence(type, connection_name)
222
+ def credential_exists?(type)
170
223
  server = ConfigFile.read_option(:server)
171
224
  response = check_credential(server, type)
172
- return if ResponseHelper.ok?(response)
225
+ !ResponseHelper.ok?(response)
226
+ end
227
+
228
+ def handle_existing_credential_options(credential_type_slug)
229
+ if options.update_credential_if_exists?
230
+ Uffizzi.ui.say('Updating existing credential.')
231
+ return
232
+ end
173
233
 
174
234
  if options.skip_raise_existence_error?
175
- Uffizzi.ui.say("Credentials of type #{connection_name} already exist for this account.")
235
+ Uffizzi.ui.say("Credential of type #{credential_type_slug} already exists for this account.")
176
236
  exit(true)
177
237
  else
178
- message = "Credentials of type #{connection_name} already exist for this account. " \
179
- "To remove them, run $ uffizzi disconnect #{connection_name}."
238
+ message = "Credential of type #{credential_type_slug} already exists for this account.\n" \
239
+ "To remove them, run uffizzi disconnect #{credential_type_slug}."
180
240
  raise Uffizzi::Error.new(message)
181
241
  end
182
242
  end
@@ -204,7 +264,7 @@ module Uffizzi
204
264
  def google_service_account_content(credential_file_path = nil)
205
265
  return ENV['GCLOUD_SERVICE_KEY'] if ENV['GCLOUD_SERVICE_KEY']
206
266
 
207
- return Uffizzi.ui.say('Path to google service account key file wasn\'t specified.') if credential_file_path.nil?
267
+ raise Uffizzi::Error.new("Path to a google service account key file wasn't specified.") if credential_file_path.nil?
208
268
 
209
269
  begin
210
270
  credential_content = File.read(credential_file_path)
@@ -10,6 +10,8 @@ module Uffizzi
10
10
  connection_type = case credential_type
11
11
  when 'docker-hub'
12
12
  Uffizzi.configuration.credential_types[:dockerhub]
13
+ when 'docker-registry'
14
+ Uffizzi.configuration.credential_types[:docker_registry]
13
15
  when 'acr'
14
16
  Uffizzi.configuration.credential_types[:azure]
15
17
  when 'ecr'
@@ -25,7 +27,7 @@ module Uffizzi
25
27
  response = delete_credential(ConfigFile.read_option(:server), connection_type)
26
28
 
27
29
  if ResponseHelper.no_content?(response)
28
- Uffizzi.ui.say("Successfully disconnected #{connection_name(credential_type)} connection")
30
+ Uffizzi.ui.say("Successfully disconnected from #{connection_name(credential_type)}.")
29
31
  else
30
32
  ResponseHelper.handle_failed_response(response)
31
33
  end
@@ -36,6 +38,7 @@ module Uffizzi
36
38
  def connection_name(credential_type)
37
39
  {
38
40
  'docker-hub' => 'DockerHub',
41
+ 'docker-registry' => 'Docker Registry',
39
42
  'acr' => 'ACR',
40
43
  'ecr' => 'ECR',
41
44
  'gcr' => 'GCR',
@@ -34,17 +34,17 @@ module Uffizzi
34
34
 
35
35
  def set_server
36
36
  config_server = ConfigFile.exists? ? read_option_from_config(:server) : nil
37
- server_address = @options[:server] || config_server || Uffizzi.ui.ask('Server: ')
37
+ server_address = (@options[:server] || config_server || Uffizzi.ui.ask('Server:')).sub(/\/+$/, '')
38
38
  server_address.start_with?('http:', 'https:') ? server_address : "https://#{server_address}"
39
39
  end
40
40
 
41
41
  def set_username
42
42
  config_username = ConfigFile.exists? ? read_option_from_config(:username) : nil
43
- @options[:username] || config_username || Uffizzi.ui.ask('Username: ')
43
+ @options[:username] || config_username || Uffizzi.ui.ask('Username:')
44
44
  end
45
45
 
46
46
  def set_password
47
- ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password: ', echo: false)
47
+ ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password:', echo: false)
48
48
  end
49
49
 
50
50
  def read_option_from_config(option)
@@ -12,19 +12,24 @@ module Uffizzi
12
12
  desc 'service', 'Show the preview services info'
13
13
  require_relative 'preview/service'
14
14
  subcommand 'service', Uffizzi::Cli::Preview::Service
15
+
15
16
  desc 'list', 'List all previews'
17
+ method_option :filter, required: false, type: :string, aliases: '-f'
18
+ method_option :output, required: false, type: :string, aliases: '-o', enum: ['json']
16
19
  def list
17
20
  run('list')
18
21
  end
19
22
 
20
23
  desc 'create [COMPOSE_FILE]', 'Create a preview'
21
24
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
25
+ method_option :"set-labels", required: false, type: :string, aliases: '-s'
22
26
  def create(file_path = nil)
23
27
  run('create', file_path: file_path)
24
28
  end
25
29
 
26
30
  desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a preview'
27
31
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
32
+ method_option :"set-labels", required: false, type: :string, aliases: '-s'
28
33
  def update(deployment_name, file_path)
29
34
  run('update', deployment_name: deployment_name, file_path: file_path)
30
35
  end
@@ -47,10 +52,7 @@ module Uffizzi
47
52
  private
48
53
 
49
54
  def run(command, file_path: nil, deployment_name: nil)
50
- unless options[:output].nil?
51
- Uffizzi.ui.output_format = options[:output]
52
- Uffizzi.ui.disable_stdout
53
- end
55
+ Uffizzi.ui.output_format = options[:output]
54
56
  raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
55
57
  raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
56
58
 
@@ -58,11 +60,11 @@ module Uffizzi
58
60
 
59
61
  case command
60
62
  when 'list'
61
- handle_list_command(project_slug)
63
+ handle_list_command(project_slug, options[:filter])
62
64
  when 'create'
63
- handle_create_command(file_path, project_slug)
65
+ handle_create_command(file_path, project_slug, options[:"set-labels"])
64
66
  when 'update'
65
- handle_update_command(deployment_name, file_path, project_slug)
67
+ handle_update_command(deployment_name, file_path, project_slug, options[:"set-labels"])
66
68
  when 'delete'
67
69
  handle_delete_command(deployment_name, project_slug)
68
70
  when 'describe'
@@ -72,8 +74,9 @@ module Uffizzi
72
74
  end
73
75
  end
74
76
 
75
- def handle_list_command(project_slug)
76
- response = fetch_deployments(ConfigFile.read_option(:server), project_slug)
77
+ def handle_list_command(project_slug, filter)
78
+ parsed_filter = filter.nil? ? {} : build_filter_params(filter)
79
+ response = fetch_deployments(ConfigFile.read_option(:server), project_slug, parsed_filter)
77
80
 
78
81
  if ResponseHelper.ok?(response)
79
82
  handle_succeed_list_response(response)
@@ -82,8 +85,10 @@ module Uffizzi
82
85
  end
83
86
  end
84
87
 
85
- def handle_create_command(file_path, project_slug)
86
- params = file_path.nil? ? {} : prepare_params(file_path)
88
+ def handle_create_command(file_path, project_slug, labels)
89
+ Uffizzi.ui.disable_stdout unless options[:output].nil?
90
+ params = prepare_params(file_path, labels)
91
+
87
92
  response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
88
93
 
89
94
  if !ResponseHelper.created?(response)
@@ -101,12 +106,13 @@ module Uffizzi
101
106
  handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
102
107
  end
103
108
 
104
- def handle_update_command(deployment_name, file_path, project_slug)
109
+ def handle_update_command(deployment_name, file_path, project_slug, labels)
110
+ Uffizzi.ui.disable_stdout unless options[:output].nil?
105
111
  deployment_id = PreviewService.read_deployment_id(deployment_name)
106
112
 
107
113
  raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
108
114
 
109
- params = prepare_params(file_path)
115
+ params = prepare_params(file_path, labels)
110
116
  response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
111
117
 
112
118
  if !ResponseHelper.ok?(response)
@@ -175,7 +181,11 @@ module Uffizzi
175
181
  raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
176
182
 
177
183
  deployments.each do |deployment|
178
- Uffizzi.ui.say("deployment-#{deployment[:id]}")
184
+ if Uffizzi.ui.output_format.nil?
185
+ Uffizzi.ui.say("deployment-#{deployment[:id]}")
186
+ else
187
+ Uffizzi.ui.pretty_say(deployment)
188
+ end
179
189
  end
180
190
  end
181
191
 
@@ -205,26 +215,10 @@ module Uffizzi
205
215
  end
206
216
  end
207
217
 
208
- def prepare_params(file_path)
209
- begin
210
- compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
211
- rescue Errno::ENOENT => e
212
- raise Uffizzi::Error.new(e.message)
213
- end
214
-
215
- compose_file_dir = File.dirname(file_path)
216
- dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
217
- absolute_path = File.absolute_path(file_path)
218
- compose_file_params = {
219
- path: absolute_path,
220
- content: Base64.encode64(compose_file_data),
221
- source: absolute_path,
222
- }
223
-
224
- {
225
- compose_file: compose_file_params,
226
- dependencies: dependencies,
227
- }
218
+ def prepare_params(file_path, labels)
219
+ compose_file_params = file_path.nil? ? {} : build_compose_file_params(file_path)
220
+ metadata_params = labels.nil? ? {} : build_metadata_params(labels)
221
+ compose_file_params.merge(metadata_params)
228
222
  end
229
223
 
230
224
  def handle_preview_interruption(deployment_id, server, project_slug)
@@ -251,10 +245,77 @@ module Uffizzi
251
245
  end
252
246
 
253
247
  def build_deployment_data(deployment)
248
+ url_server = ConfigFile.read_option(:server)
249
+
254
250
  {
255
251
  id: "deployment-#{deployment[:id]}",
256
252
  url: "https://#{deployment[:preview_url]}",
253
+ containers_uri: "#{url_server}/projects/#{deployment[:project_id]}/deployments/#{deployment[:id]}/containers",
257
254
  }
258
255
  end
256
+
257
+ def build_compose_file_params(file_path)
258
+ begin
259
+ compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
260
+ rescue Errno::ENOENT => e
261
+ raise Uffizzi::Error.new(e.message)
262
+ end
263
+
264
+ compose_file_dir = File.dirname(file_path)
265
+ dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
266
+ absolute_path = File.absolute_path(file_path)
267
+ compose_file_params = {
268
+ path: absolute_path,
269
+ content: Base64.encode64(compose_file_data),
270
+ source: absolute_path,
271
+ }
272
+
273
+ {
274
+ compose_file: compose_file_params,
275
+ dependencies: dependencies,
276
+ }
277
+ end
278
+
279
+ def build_metadata_params(labels)
280
+ {
281
+ metadata: {
282
+ 'labels' => parse_params(labels, 'Labels'),
283
+ },
284
+ }
285
+ end
286
+
287
+ def build_filter_params(filter_params)
288
+ {
289
+ 'labels' => parse_params(filter_params, 'Filtering parameters'),
290
+ }
291
+ end
292
+
293
+ def parse_params(params, params_type)
294
+ validate_params(params, params_type)
295
+ params.split(' ').reduce({}) do |acc, param|
296
+ stringified_keys, value = param.split('=', 2)
297
+ keys = stringified_keys.split('.', -1)
298
+ inner_pair = { keys.pop => value }
299
+ prepared_param = keys.reverse.reduce(inner_pair) { |res, key| { key => res } }
300
+ merge_params(acc, prepared_param)
301
+ end
302
+ end
303
+
304
+ def validate_params(params, params_type)
305
+ params.split(' ').each do |param|
306
+ stringified_keys, value = param.split('=', 2)
307
+ raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if value.nil? || stringified_keys.nil? || value.empty?
308
+
309
+ keys = stringified_keys.split('.', -1)
310
+ raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if keys.empty? || keys.any?(&:empty?)
311
+ end
312
+ end
313
+
314
+ def merge_params(result, param)
315
+ key = param.keys.first
316
+ return result.merge(param) unless result.has_key?(key)
317
+
318
+ { key => result[key].merge(merge_params(result[key], param[key])) }
319
+ end
259
320
  end
260
321
  end
@@ -70,6 +70,13 @@ module ApiClient
70
70
  build_response(response)
71
71
  end
72
72
 
73
+ def update_credential(server, params, type)
74
+ uri = credential_uri(server, type)
75
+ response = http_client.make_put_request(uri, params)
76
+
77
+ build_response(response)
78
+ end
79
+
73
80
  def fetch_deployment_services(server, project_slug, deployment_id)
74
81
  uri = preview_services_uri(server, project_slug, deployment_id)
75
82
  response = http_client.make_get_request(uri)
@@ -78,7 +85,7 @@ module ApiClient
78
85
  end
79
86
 
80
87
  def delete_credential(server, credential_type)
81
- uri = delete_credential_uri(server, credential_type)
88
+ uri = credential_uri(server, credential_type)
82
89
  response = http_client.make_delete_request(uri)
83
90
 
84
91
  build_response(response)
@@ -140,8 +147,8 @@ module ApiClient
140
147
  build_response(response)
141
148
  end
142
149
 
143
- def fetch_deployments(server, project_slug)
144
- uri = deployments_uri(server, project_slug)
150
+ def fetch_deployments(server, project_slug, filter)
151
+ uri = deployments_uri(server, project_slug, filter)
145
152
  response = http_client.make_get_request(uri)
146
153
 
147
154
  build_response(response)
@@ -32,8 +32,10 @@ module ApiRoutes
32
32
  "#{compose_files_uri(server, project_slug)}/validate"
33
33
  end
34
34
 
35
- def deployments_uri(server, project_slug)
36
- "#{server}/api/cli/v1/projects/#{project_slug}/deployments"
35
+ def deployments_uri(server, project_slug, filter = nil)
36
+ return "#{server}/api/cli/v1/projects/#{project_slug}/deployments" if filter.nil?
37
+
38
+ "#{server}/api/cli/v1/projects/#{project_slug}/deployments?q=#{filter.to_json}"
37
39
  end
38
40
 
39
41
  def deployment_uri(server, project_slug, deployment_id)
@@ -64,7 +66,7 @@ module ApiRoutes
64
66
  "#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers"
65
67
  end
66
68
 
67
- def delete_credential_uri(server, credential_type)
69
+ def credential_uri(server, credential_type)
68
70
  "#{server}/api/cli/v1/account/credentials/#{credential_type}"
69
71
  end
70
72
 
@@ -50,13 +50,13 @@ module Uffizzi
50
50
  headers = { 'Content-Type' => 'application/json' }
51
51
  request = case method
52
52
  when :get
53
- Net::HTTP::Get.new(uri.path, headers)
53
+ Net::HTTP::Get.new(uri.request_uri, headers)
54
54
  when :post
55
- Net::HTTP::Post.new(uri.path, headers)
55
+ Net::HTTP::Post.new(uri.request_uri, headers)
56
56
  when :delete
57
- Net::HTTP::Delete.new(uri.path, headers)
57
+ Net::HTTP::Delete.new(uri.request_uri, headers)
58
58
  when :put
59
- Net::HTTP::Put.new(uri.path, headers)
59
+ Net::HTTP::Put.new(uri.request_uri, headers)
60
60
  end
61
61
  if request.instance_of?(Net::HTTP::Post) || request.instance_of?(Net::HTTP::Put)
62
62
  request.body = params.to_json