hammer_cli_katello 0.19.2 → 0.20.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 +4 -4
- data/lib/hammer_cli_katello.rb +2 -5
- data/lib/hammer_cli_katello/command_extensions.rb +1 -0
- data/lib/hammer_cli_katello/command_extensions/ping.rb +26 -0
- data/lib/hammer_cli_katello/commands.rb +4 -1
- data/lib/hammer_cli_katello/content_view.rb +5 -0
- data/lib/hammer_cli_katello/content_view_version.rb +10 -11
- data/lib/hammer_cli_katello/cv_import_export_helper.rb +39 -41
- data/lib/hammer_cli_katello/filter_rule.rb +4 -1
- data/lib/hammer_cli_katello/organization.rb +2 -1
- data/lib/hammer_cli_katello/output/formatters.rb +2 -2
- data/lib/hammer_cli_katello/ping.rb +12 -11
- data/lib/hammer_cli_katello/repository.rb +28 -80
- data/lib/hammer_cli_katello/status.rb +23 -0
- data/lib/hammer_cli_katello/version.rb +1 -1
- data/test/data/3.14/foreman_api.json +1 -0
- data/test/functional/activation_key/subscriptions_test.rb +5 -7
- data/test/functional/content_view/version/export_test.rb +3 -194
- data/test/functional/ping_test.rb +1 -1
- data/test/functional/repository/update_test.rb +0 -54
- data/test/functional/repository/upload_test.rb +21 -14
- data/test/functional/subscription/list_test.rb +0 -6
- data/test/test_helper.rb +1 -1
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a27a924ef525708ffb735aa5dd369d47da3f2832e935110b51786cb82f74cb96
|
4
|
+
data.tar.gz: 60964599cd0f257228da611d8de998e11213c98726120d1bb8a12d0f13b215a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fd3cc4a42fecbb77241beea5d9871bfcc7290473088dfb68741082dbe9d4dd96f450dac72c7151894652a3d85ce142365ab3a885add5b30d8c6da503e8574d5
|
7
|
+
data.tar.gz: c73dabc6e9676b5385f91668e9c0c74a2c48dc956ea24a8ba7cb12545ebdfdbfcf51f84498e76953f0c70b4adb6e05b9127cfa194fe47c8c0a66fe119e65707f
|
data/lib/hammer_cli_katello.rb
CHANGED
@@ -54,11 +54,6 @@ module HammerCLIKatello
|
|
54
54
|
'hammer_cli_katello/lifecycle_environment'
|
55
55
|
)
|
56
56
|
|
57
|
-
HammerCLI::MainCommand.lazy_subcommand("ping", _("Get the status of the server"),
|
58
|
-
'HammerCLIKatello::PingCommand',
|
59
|
-
'hammer_cli_katello/ping'
|
60
|
-
)
|
61
|
-
|
62
57
|
HammerCLI::MainCommand.lazy_subcommand("product", _("Manipulate products"),
|
63
58
|
'HammerCLIKatello::Product',
|
64
59
|
'hammer_cli_katello/product'
|
@@ -144,5 +139,7 @@ module HammerCLIKatello
|
|
144
139
|
# subcommands to hammer_cli_foreman commands
|
145
140
|
require 'hammer_cli_katello/host'
|
146
141
|
require 'hammer_cli_katello/hostgroup'
|
142
|
+
require 'hammer_cli_katello/ping'
|
143
|
+
require 'hammer_cli_katello/status'
|
147
144
|
end
|
148
145
|
# rubocop:enable Metrics/ModuleLength
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module HammerCLIKatello
|
2
|
+
module CommandExtensions
|
3
|
+
class Ping < HammerCLI::CommandExtensions
|
4
|
+
before_print do |data|
|
5
|
+
unless data['results']['katello'].nil?
|
6
|
+
data['results']['katello']['services'].each do |_, service|
|
7
|
+
service['_response'] = get_server_response(service)
|
8
|
+
end
|
9
|
+
data['results'].merge!(data['results']['katello'])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
output do |definition|
|
14
|
+
definition.append(HammerCLIKatello::PingCommand.output_definition.fields)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_server_response(service_hash)
|
18
|
+
if service_hash['duration_ms']
|
19
|
+
_("Duration: %sms") % service_hash['duration_ms']
|
20
|
+
elsif service_hash['message']
|
21
|
+
_("Message: %s") % service_hash['message']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -283,6 +283,11 @@ module HammerCLIKatello
|
|
283
283
|
command_name 'add-version'
|
284
284
|
desc _('Add a content view version to a composite view')
|
285
285
|
|
286
|
+
option "--content-view-id", "CONTENT_VIEW_ID",
|
287
|
+
_("Content view numeric identifier to search by"),
|
288
|
+
attribute_name: :option_content_view_id,
|
289
|
+
format: HammerCLI::Options::Normalizers::Number.new
|
290
|
+
|
286
291
|
validate_options :before, 'IdResolution' do
|
287
292
|
if option(:option_content_view_version_version).exist?
|
288
293
|
any(:option_content_view_id, :option_content_view_name).required
|
@@ -372,10 +372,7 @@ module HammerCLIKatello
|
|
372
372
|
end
|
373
373
|
export_json_options[:repositories] = []
|
374
374
|
else
|
375
|
-
repositories =
|
376
|
-
puppet_check(cvv)
|
377
|
-
check_repo_type(repositories)
|
378
|
-
check_repo_download_policy(repositories)
|
375
|
+
repositories = fetch_exportable_cvv_repositories(cvv)
|
379
376
|
collect_packages(repositories)
|
380
377
|
|
381
378
|
export_json_options[:repositories] = repositories
|
@@ -480,11 +477,14 @@ module HammerCLIKatello
|
|
480
477
|
publish(cv['id'], export_json['major'], export_json['minor'])
|
481
478
|
else
|
482
479
|
sync_repositories(export_json['repositories'], options['option_organization_id'],
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
480
|
+
import_tar_params)
|
481
|
+
|
482
|
+
unless cv['default']
|
483
|
+
publish(
|
484
|
+
cv['id'], export_json['major'],
|
485
|
+
export_json['minor'], repos_units(export_json['repositories'])
|
486
|
+
)
|
487
|
+
end
|
488
488
|
end
|
489
489
|
return HammerCLI::EX_OK
|
490
490
|
end
|
@@ -498,8 +498,7 @@ module HammerCLIKatello
|
|
498
498
|
library_repos = index(
|
499
499
|
:repositories,
|
500
500
|
'organization_id' => organization_id,
|
501
|
-
'library' => true
|
502
|
-
'label' => repo['label']
|
501
|
+
'library' => true
|
503
502
|
)
|
504
503
|
|
505
504
|
library_repo = library_repos.select do |candidate_repo|
|
@@ -3,10 +3,32 @@ module HammerCLIKatello
|
|
3
3
|
module CVImportExportHelper
|
4
4
|
PUBLISHED_REPOS_DIR = "/var/lib/pulp/published/yum/https/repos/".freeze
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
6
|
+
def fetch_exportable_cvv_repositories(cvv)
|
7
|
+
immediate = []
|
8
|
+
non_immediate_names = []
|
9
|
+
|
10
|
+
cvv['repositories'].each do |repo|
|
11
|
+
next unless repo['content_type'] == 'yum'
|
12
|
+
|
13
|
+
api_repo = show(:repositories, 'id' => repo['id'], :full_result => true)
|
14
|
+
|
15
|
+
download_policy = if api_repo['library_instance_id']
|
16
|
+
library = show(:repositories, 'id' => api_repo['library_instance_id'])
|
17
|
+
library['download_policy']
|
18
|
+
else
|
19
|
+
api_repo['download_policy']
|
20
|
+
end
|
21
|
+
|
22
|
+
if download_policy == 'immediate'
|
23
|
+
immediate << api_repo
|
24
|
+
else
|
25
|
+
non_immediate_names << api_repo['name']
|
26
|
+
end
|
9
27
|
end
|
28
|
+
|
29
|
+
warn_repo_download_policy(non_immediate_names)
|
30
|
+
|
31
|
+
return immediate
|
10
32
|
end
|
11
33
|
|
12
34
|
def find_local_component_id(component_from_export)
|
@@ -23,41 +45,15 @@ module HammerCLIKatello
|
|
23
45
|
found_composite_version.first['id']
|
24
46
|
end
|
25
47
|
|
26
|
-
def
|
27
|
-
|
28
|
-
raise _("The Content View '#{cvv['content_view']['label']}'"\
|
29
|
-
" contains Puppet modules, this is not supported at this time."\
|
30
|
-
" Please remove the modules, publish a new version"\
|
31
|
-
" and try the export again.")
|
32
|
-
end
|
33
|
-
end
|
48
|
+
def warn_repo_download_policy(repository_names)
|
49
|
+
return if repository_names.empty?
|
34
50
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
" republish and try the export again.")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def check_repo_download_policy(repositories)
|
47
|
-
non_immediate = repositories.select do |repo|
|
48
|
-
unless repo['library_instance_id'].nil?
|
49
|
-
show(:repositories, 'id' => repo['library_instance_id'])['download_policy'] != 'immediate'
|
50
|
-
end
|
51
|
-
end
|
52
|
-
unless non_immediate.empty?
|
53
|
-
non_immediate_names = non_immediate.collect { |repo| repo['name'] }
|
54
|
-
msg = <<~MSG
|
55
|
-
All exported repositories must be set to an immediate download policy and re-synced.
|
56
|
-
The following repositories need action:
|
57
|
-
#{non_immediate_names.join(', ')}
|
58
|
-
MSG
|
59
|
-
raise _(msg)
|
60
|
-
end
|
51
|
+
msg = <<~MSG
|
52
|
+
The following repositories could not be exported due to the download policy
|
53
|
+
not being set to 'immediate':
|
54
|
+
#{repository_names.join(', ')}
|
55
|
+
MSG
|
56
|
+
print_message msg
|
61
57
|
end
|
62
58
|
|
63
59
|
def collect_packages(repositories)
|
@@ -88,10 +84,12 @@ module HammerCLIKatello
|
|
88
84
|
" please create the Content View and try the import again.")
|
89
85
|
end
|
90
86
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
87
|
+
unless import_cv['default']
|
88
|
+
if import_cv['latest_version'].to_f >= version
|
89
|
+
raise _("The latest version (#{import_cv['latest_version']}) of"\
|
90
|
+
" the Content View '#{cv['name']}'"\
|
91
|
+
" is greater or equal to the version you are trying to import (#{version})")
|
92
|
+
end
|
95
93
|
end
|
96
94
|
|
97
95
|
unless import_cv['repository_ids'].nil?
|
@@ -37,7 +37,8 @@ module HammerCLIKatello
|
|
37
37
|
build_options
|
38
38
|
end
|
39
39
|
|
40
|
-
class CreateCommand <
|
40
|
+
class CreateCommand < HammerCLIForeman::Organization::CreateCommand
|
41
|
+
include HammerCLIKatello::ResolverCommons
|
41
42
|
resource :organizations, :create
|
42
43
|
|
43
44
|
success_message _("Organization created.")
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'hammer_cli_foreman/ping'
|
2
|
+
|
1
3
|
module HammerCLIKatello
|
2
4
|
class PingCommand < HammerCLIKatello::Command
|
3
5
|
resource :ping, :index
|
@@ -54,24 +56,23 @@ module HammerCLIKatello
|
|
54
56
|
|
55
57
|
def send_request
|
56
58
|
super.tap do |data|
|
59
|
+
data['services'] ||= {}
|
57
60
|
data['services'].each do |_, service|
|
58
|
-
service['_response'] =
|
61
|
+
service['_response'] =
|
62
|
+
HammerCLIKatello::CommandExtensions::Ping.get_server_response(service)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
63
|
-
private
|
64
|
-
|
65
|
-
def get_server_response(service_hash)
|
66
|
-
if service_hash['duration_ms']
|
67
|
-
_("Duration: %sms") % service_hash['duration_ms']
|
68
|
-
elsif service_hash['message']
|
69
|
-
_("Message: %s") % service_hash['message']
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
67
|
def request_options
|
74
68
|
{ with_authentication: false }
|
75
69
|
end
|
76
70
|
end # class PingCommand
|
71
|
+
|
72
|
+
HammerCLIForeman::PingCommand.subcommand 'katello',
|
73
|
+
HammerCLIKatello::PingCommand.desc,
|
74
|
+
HammerCLIKatello::PingCommand
|
75
|
+
HammerCLIForeman::PingCommand::ForemanCommand.extend_with(
|
76
|
+
HammerCLIKatello::CommandExtensions::Ping.new
|
77
|
+
)
|
77
78
|
end # module HammerCLIKatello
|
@@ -212,13 +212,6 @@ module HammerCLIKatello
|
|
212
212
|
if option(:option_product_name).exist?
|
213
213
|
any(*organization_options).required
|
214
214
|
end
|
215
|
-
|
216
|
-
if option(:option_docker_tag).exist? != option(:option_docker_digest).exist?
|
217
|
-
option(:option_docker_tag).rejected(
|
218
|
-
:msg => _('--docker-digest required with --docker-tag'))
|
219
|
-
option(:option_docker_digest).rejected(
|
220
|
-
:msg => _('--docker-tag required with --docker-digest'))
|
221
|
-
end
|
222
215
|
end
|
223
216
|
|
224
217
|
build_options(:without => [:unprotected]) do |o|
|
@@ -227,60 +220,12 @@ module HammerCLIKatello
|
|
227
220
|
option "--publish-via-http", "ENABLE", _("Publish Via HTTP"),
|
228
221
|
:attribute_name => :option_unprotected,
|
229
222
|
:format => HammerCLI::Options::Normalizers::Bool.new
|
230
|
-
option "--docker-tag", "TAG",
|
231
|
-
_("Optional custom Container Image tag to specify the value of the Docker digest")
|
232
|
-
option "--docker-digest", "DIGEST", _("Container Image manifest digest")
|
233
223
|
|
234
224
|
def execute
|
235
225
|
@failure = false
|
236
|
-
|
237
|
-
if option_docker_tag
|
238
|
-
upload_tag(option_docker_tag, option_docker_digest)
|
239
|
-
else
|
240
|
-
super
|
241
|
-
end
|
242
|
-
|
226
|
+
super
|
243
227
|
@failure ? HammerCLI::EX_DATAERR : HammerCLI::EX_OK
|
244
228
|
end
|
245
|
-
|
246
|
-
def content_upload_resource
|
247
|
-
::HammerCLIForeman.foreman_resource(:content_uploads)
|
248
|
-
end
|
249
|
-
|
250
|
-
def upload_tag(tag, digest)
|
251
|
-
upload_id = create_content_upload
|
252
|
-
import_uploads([
|
253
|
-
{
|
254
|
-
id: upload_id,
|
255
|
-
name: tag,
|
256
|
-
digest: digest
|
257
|
-
}
|
258
|
-
], last_file: true)
|
259
|
-
print_message _("Repository updated")
|
260
|
-
rescue => e
|
261
|
-
@failure = true
|
262
|
-
logger.error e
|
263
|
-
output.print_error _("Failed to upload tag '%s' to repository.") % tag
|
264
|
-
ensure
|
265
|
-
content_upload_resource.call(:destroy, :repository_id => get_identifier, :id => upload_id)
|
266
|
-
end
|
267
|
-
|
268
|
-
def create_content_upload
|
269
|
-
response = content_upload_resource.call(:create, :repository_id => get_identifier)
|
270
|
-
|
271
|
-
response["upload_id"]
|
272
|
-
end
|
273
|
-
|
274
|
-
def import_uploads(uploads, opts = {})
|
275
|
-
publish_repository = opts.fetch(:last_file, false)
|
276
|
-
sync_capsule = opts.fetch(:last_file, false)
|
277
|
-
params = {:id => get_identifier,
|
278
|
-
:uploads => uploads,
|
279
|
-
publish_repository: publish_repository,
|
280
|
-
sync_capsule: sync_capsule
|
281
|
-
}
|
282
|
-
resource.call(:import_uploads, params)
|
283
|
-
end
|
284
229
|
end
|
285
230
|
|
286
231
|
class DeleteCommand < HammerCLIKatello::DeleteCommand
|
@@ -382,38 +327,41 @@ module HammerCLIKatello
|
|
382
327
|
private
|
383
328
|
|
384
329
|
def upload_file(file, opts = {})
|
385
|
-
|
386
|
-
|
330
|
+
total_size = File.size(file)
|
331
|
+
checksum = Digest::SHA256.hexdigest(File.read(file))
|
332
|
+
content_type = options["option_content_type"] ? options["option_content_type"] : nil
|
387
333
|
filename = File.basename(file.path)
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
334
|
+
upload_create_response = create_content_upload(total_size, checksum, content_type)
|
335
|
+
upload_id = upload_create_response["upload_id"] || "duplicate"
|
336
|
+
content_unit_id = upload_create_response["content_unit_href"]
|
337
|
+
unless content_unit_id
|
338
|
+
repo_id = get_identifier
|
339
|
+
update_content_upload(upload_id, repo_id, file)
|
340
|
+
end
|
394
341
|
results = import_uploads([
|
395
342
|
{
|
396
343
|
id: upload_id,
|
344
|
+
content_unit_id: content_unit_id,
|
397
345
|
name: filename,
|
398
346
|
size: file.size,
|
399
|
-
checksum:
|
400
|
-
}
|
401
|
-
], opts)
|
402
|
-
|
347
|
+
checksum: checksum
|
348
|
+
}], opts)
|
403
349
|
print_results(filename, results)
|
404
|
-
rescue => e
|
405
|
-
@failure = true
|
406
|
-
logger.error e
|
407
|
-
output.print_error _("Failed to upload file '%s' to repository. Please check "\
|
408
|
-
"the file and try again.") % filename
|
409
350
|
ensure
|
410
|
-
|
351
|
+
if upload_id
|
352
|
+
content_upload_resource.call(:destroy, :repository_id => get_identifier, :id => upload_id)
|
353
|
+
end
|
411
354
|
end
|
412
355
|
|
413
|
-
def create_content_upload
|
414
|
-
|
415
|
-
|
416
|
-
|
356
|
+
def create_content_upload(size, checksum, content_type)
|
357
|
+
params = {
|
358
|
+
:repository_id => get_identifier,
|
359
|
+
:size => size,
|
360
|
+
:checksum => checksum,
|
361
|
+
:content_type => content_type
|
362
|
+
}
|
363
|
+
response = content_upload_resource.call(:create, params)
|
364
|
+
response
|
417
365
|
end
|
418
366
|
|
419
367
|
def update_content_upload(upload_id, repo_id, file)
|
@@ -424,10 +372,10 @@ module HammerCLIKatello
|
|
424
372
|
:offset => offset,
|
425
373
|
:id => upload_id,
|
426
374
|
:content => content,
|
375
|
+
:size => file.size,
|
427
376
|
:repository_id => repo_id,
|
428
377
|
:multipart => true
|
429
378
|
}
|
430
|
-
|
431
379
|
# To workaround rest-client bug with false negative warnings,
|
432
380
|
# see https://github.com/rest-client/rest-client/pull/670 for more details
|
433
381
|
silence_warnings do
|
@@ -450,7 +398,7 @@ module HammerCLIKatello
|
|
450
398
|
end
|
451
399
|
|
452
400
|
def print_results(name, results)
|
453
|
-
if results.empty?
|
401
|
+
if results.empty? || results.dig('output', 'upload_results').empty?
|
454
402
|
print_message _("Successfully uploaded file '%{name}'") % {
|
455
403
|
:name => name
|
456
404
|
}
|