hammer_cli_katello 0.14.1 → 0.15.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hammer_cli_katello/apipie_helper.rb +15 -0
  3. data/lib/hammer_cli_katello/associating_commands.rb +6 -2
  4. data/lib/hammer_cli_katello/commands.rb +7 -0
  5. data/lib/hammer_cli_katello/content_view_purge.rb +1 -1
  6. data/lib/hammer_cli_katello/content_view_version.rb +238 -2
  7. data/lib/hammer_cli_katello/erratum.rb +4 -0
  8. data/lib/hammer_cli_katello/file.rb +4 -6
  9. data/lib/hammer_cli_katello/foreman_search_options_creators.rb +1 -1
  10. data/lib/hammer_cli_katello/id_resolver.rb +2 -0
  11. data/lib/hammer_cli_katello/local_helper.rb +9 -0
  12. data/lib/hammer_cli_katello/module_stream.rb +69 -0
  13. data/lib/hammer_cli_katello/module_stream_profile.rb +0 -0
  14. data/lib/hammer_cli_katello/ostree_branch.rb +4 -0
  15. data/lib/hammer_cli_katello/package_group.rb +4 -0
  16. data/lib/hammer_cli_katello/puppet_module.rb +4 -0
  17. data/lib/hammer_cli_katello/repository.rb +21 -7
  18. data/lib/hammer_cli_katello/repository_scoped_to_product.rb +3 -3
  19. data/lib/hammer_cli_katello/search_options_creators.rb +10 -2
  20. data/lib/hammer_cli_katello/sync_plan.rb +6 -8
  21. data/lib/hammer_cli_katello/version.rb +1 -1
  22. data/lib/hammer_cli_katello.rb +9 -0
  23. data/test/data/3.8/foreman_api.json +1 -1
  24. data/test/data/3.9/foreman_api.json +1 -0
  25. data/test/functional/apipie_helper_test.rb +26 -0
  26. data/test/functional/content_view/publish_test.rb +20 -0
  27. data/test/functional/content_view/version/export_test.rb +87 -0
  28. data/test/functional/content_view/version/import_test.rb +111 -0
  29. data/test/functional/content_view/version/incremental_update_test.rb +0 -0
  30. data/test/functional/local_helper_test.rb +30 -0
  31. data/test/functional/module_stream/info_test.rb +58 -0
  32. data/test/functional/module_stream/list_test.rb +53 -0
  33. data/test/functional/package_group/list_test.rb +14 -9
  34. data/test/functional/sync_plan/create_test.rb +60 -0
  35. data/test/functional/sync_plan/delete_test.rb +46 -0
  36. data/test/functional/sync_plan/update_test.rb +44 -0
  37. data/test/test_helper.rb +1 -1
  38. data/test/unit/search_options_creators_test.rb +4 -1
  39. metadata +30 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 020a802118e1d02ce02183915e5d3c27d17fc9a5
4
- data.tar.gz: 1c481ed3adf302f0dd8162f133c4e14d87b1ccd7
3
+ metadata.gz: 81a158e8e77bef73123e89992746c3b24f9689ef
4
+ data.tar.gz: 417e144685491e014455d2c1eacb1d8caaba7d40
5
5
  SHA512:
6
- metadata.gz: 4af3a91c622735ba6df894b0bdcd1feeda752f063fdf0bc2b8902ba3de47908cf263f3918e52201f5da4378f677de02ee6608605f5e7b5b4dbcc80544023d1ed
7
- data.tar.gz: 818cac4835323c945ef06b618d9b510a427c2954df30cdd2250d5bf9e7857a827d7944ad819b53d7cee45d8359869ccb602e3c4d78e3860f6682540b5626450b
6
+ metadata.gz: 3c53985e39d45ba73ac11d19e1cf4ea3c40f60204ac98d9f86f01cb8d69c556df92889fd89965b35b93500a7d4a93b5123b48790ea3575a8f57866765b79d7ad
7
+ data.tar.gz: 64a6b70c343bafd39bb7bce8db5bd1b029a9bdb13769befb5ddd0441c33b3fdd443779a3859f8b9c1b1dc0e5f0c4db28b7c1a351f5a82103cd936a1e4a878c06
@@ -0,0 +1,15 @@
1
+ module HammerCLIKatello
2
+ module ApipieHelper
3
+ def show(resource, options = {})
4
+ call(:show, resource, options)
5
+ end
6
+
7
+ def index(resource, options = {})
8
+ call(:index, resource, options)['results']
9
+ end
10
+
11
+ def call(action, resource, options = {})
12
+ HammerCLIForeman.foreman_resource(resource).call(action, options)
13
+ end
14
+ end
15
+ end
@@ -23,8 +23,10 @@ module HammerCLIKatello
23
23
 
24
24
  class AddRepositoryCommand < HammerCLIKatello::AddAssociatedCommand
25
25
  extend AddProductOptions
26
- include RepositoryScopedToProduct
26
+ extend RepositoryScopedToProduct
27
27
  include OrganizationOptions
28
+
29
+ validate_repo_name_requires_product_options
28
30
  command_name 'add-repository'
29
31
  associated_resource :repositories
30
32
 
@@ -39,8 +41,10 @@ module HammerCLIKatello
39
41
 
40
42
  class RemoveRepositoryCommand < HammerCLIKatello::RemoveAssociatedCommand
41
43
  extend AddProductOptions
42
- include RepositoryScopedToProduct
44
+ extend RepositoryScopedToProduct
43
45
  include OrganizationOptions
46
+
47
+ validate_repo_name_requires_product_options
44
48
  command_name 'remove-repository'
45
49
  associated_resource :repositories
46
50
 
@@ -43,6 +43,13 @@ module HammerCLIKatello
43
43
 
44
44
  class ListCommand < HammerCLIForeman::ListCommand
45
45
  include HammerCLIKatello::ResolverCommons
46
+
47
+ def self.build_options(builder_params = {}, &block)
48
+ # remove --sort-by and --sort-order in favor of the Foreman's --order
49
+ builder_params[:without] ||= []
50
+ builder_params[:without] += %i(sort_by sort_order)
51
+ super(builder_params, &block)
52
+ end
46
53
  end
47
54
 
48
55
  class InfoCommand < HammerCLIForeman::InfoCommand
@@ -53,7 +53,7 @@ module HammerCLIKatello
53
53
  end
54
54
 
55
55
  def execute
56
- if option_count < 0
56
+ if option_count.negative?
57
57
  output.print_error _("Invalid value for --count option: value must be 0 or greater.")
58
58
  return HammerCLI::EX_USAGE
59
59
  end
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module HammerCLIKatello
2
4
  class ContentViewVersion < HammerCLIKatello::Command
3
5
  resource :content_view_versions
@@ -245,11 +247,12 @@ module HammerCLIKatello
245
247
  end
246
248
  end
247
249
 
248
- class ExportCommand < HammerCLIKatello::SingleResourceCommand
250
+ class LegacyExportCommand < HammerCLIKatello::SingleResourceCommand
249
251
  include HammerCLIForemanTasks::Async
252
+ desc _('Export a content view (deprecated)')
250
253
 
251
254
  action :export
252
- command_name "export"
255
+ command_name "export-legacy"
253
256
 
254
257
  success_message _("Content view is being exported in task %{id}.")
255
258
  failure_message _("Could not export the content view")
@@ -259,6 +262,239 @@ module HammerCLIKatello
259
262
  end
260
263
  end
261
264
 
265
+ class ExportCommand < HammerCLIForeman::Command
266
+ include HammerCLIKatello::LocalHelper
267
+ include HammerCLIKatello::ApipieHelper
268
+
269
+ PUBLISHED_REPOS_DIR = "/var/lib/pulp/published/yum/https/repos/".freeze
270
+
271
+ desc _('Export a content view version')
272
+
273
+ command_name "export"
274
+
275
+ success_message _("Content view export is available in %{directory}.")
276
+ failure_message _("Could not export the content view")
277
+
278
+ option "--id", "ID", _("Content View Version numeric identifier")
279
+ option '--export-dir', 'EXPORT_DIR', _("Directory to put content view version export into.")
280
+
281
+ validate_options do
282
+ option(:option_export_dir).required
283
+ option(:option_id).required
284
+ end
285
+
286
+ build_options
287
+
288
+ def execute
289
+ cvv = show(:content_view_versions, 'id' => options['option_id'])
290
+ repositories = cvv['repositories'].collect do |repo|
291
+ show(:repositories, 'id' => repo['id'], :full_result => true)
292
+ end
293
+
294
+ check_repo_download_policy(repositories)
295
+
296
+ repositories.each do |repo|
297
+ repo['packages'] = index(:packages, 'repository_id' => repo['id'], :full_result => true)
298
+ repo['errata'] = index(:errata, 'repository_id' => repo['id'], :full_result => true)
299
+ end
300
+
301
+ json = export_json(cvv, repositories)
302
+ create_tar(cvv, repositories, json)
303
+ return HammerCLI::EX_OK
304
+ end
305
+
306
+ def create_tar(cvv, repositories, json)
307
+ export_prefix = "export-#{cvv['id']}"
308
+ export_file = "#{export_prefix}.json"
309
+ export_repos_tar = "#{export_prefix}-repos.tar"
310
+ export_tar = "#{export_prefix}.tar"
311
+
312
+ Dir.mkdir("#{options['option_export_dir']}/#{export_prefix}")
313
+
314
+ Dir.chdir(PUBLISHED_REPOS_DIR) do
315
+ repo_tar = "#{options['option_export_dir']}/#{export_prefix}/#{export_repos_tar}"
316
+ repo_dirs = []
317
+
318
+ repositories.each do |repo|
319
+ repo_dirs.push(repo['relative_path'])
320
+ end
321
+
322
+ `tar cvfh #{repo_tar} #{repo_dirs.join(" ")}`
323
+ end
324
+
325
+ Dir.chdir("#{options['option_export_dir']}/#{export_prefix}") do
326
+ File.open(export_file, 'w') do |file|
327
+ file.write(JSON.pretty_generate(json))
328
+ end
329
+ end
330
+
331
+ Dir.chdir(options['option_export_dir']) do
332
+ `tar cf #{export_tar} #{export_prefix}`
333
+ FileUtils.rm_rf(export_prefix)
334
+ end
335
+ end
336
+
337
+ def check_repo_download_policy(repositories)
338
+ on_demand = repositories.select do |repo|
339
+ show(:repositories, 'id' => repo['library_instance_id'])['download_policy'] == 'on_demand'
340
+ end
341
+ return true if on_demand.empty?
342
+
343
+ on_demand_names = repositories.collect { |repo| repo['name'] }
344
+ msg = <<~MSG
345
+ All exported repositories must be set to an immediate download policy and re-synced.
346
+ The following repositories need action:
347
+ #{on_demand_names.join('\n')}
348
+ MSG
349
+ raise _(msg)
350
+ end
351
+
352
+ def export_json(content_view_version, repositories)
353
+ json = {
354
+ "name" => content_view_version['content_view']['name'],
355
+ "major" => content_view_version['major'],
356
+ "minor" => content_view_version['minor']
357
+ }
358
+
359
+ json["repositories"] = repositories.collect do |repo|
360
+ {
361
+ "id" => repo['id'],
362
+ "label" => repo['label'],
363
+ "content_type" => repo['content_type'],
364
+ "backend_identifier" => repo['backend_identifier'],
365
+ "relative_path" => repo['relative_path'],
366
+ "on_disk_path" => "#{PUBLISHED_REPOS_DIR}/#{repo['relative_path']}",
367
+ "rpm_filenames" => repo['packages'].collect { |package| package['filename'] },
368
+ "errata_ids" => repo['errata'].collect { |errata| errata['errata_id'] }
369
+ }
370
+ end
371
+
372
+ json
373
+ end
374
+ end
375
+
376
+ class ImportCommand < HammerCLIForeman::Command
377
+ include HammerCLIForemanTasks::Async
378
+ include HammerCLIKatello::LocalHelper
379
+ include HammerCLIKatello::ApipieHelper
380
+
381
+ attr_accessor :export_tar_dir, :export_tar_file, :export_tar_prefix
382
+
383
+ desc _('Import a content view version')
384
+
385
+ command_name "import"
386
+
387
+ success_message _("Content view imported.")
388
+ failure_message _("Could not import the content view.")
389
+
390
+ option "--organization-id", "ORGANIZATION_ID", _("Organization numeric identifier")
391
+ option(
392
+ '--export-tar',
393
+ 'EXPORT_TAR',
394
+ _("Location of export tar on disk")
395
+ )
396
+
397
+ validate_options do
398
+ option(:option_export_tar).required
399
+ option(:option_organization_id).required
400
+ end
401
+
402
+ build_options
403
+
404
+ def execute
405
+ unless File.exist?(options['option_export_tar'])
406
+ raise _("Export tar #{options['option_export_tar']} does not exist.")
407
+ end
408
+
409
+ self.export_tar_file = File.basename(options['option_export_tar'])
410
+ self.export_tar_prefix = @export_tar_file.gsub('.tar', '')
411
+ self.export_tar_dir = File.dirname(options['option_export_tar'])
412
+ untar_export
413
+
414
+ export_json = read_json
415
+
416
+ cv = content_view(export_json['name'], options['option_organization_id'])
417
+ sync_repositories(export_json['repositories'], options['option_organization_id'])
418
+
419
+ publish(
420
+ cv['id'],
421
+ export_json['major'],
422
+ export_json['minor'],
423
+ repos_units(export_json['repositories'])
424
+ )
425
+ return HammerCLI::EX_OK
426
+ end
427
+
428
+ def untar_export
429
+ Dir.chdir(@export_tar_dir) do
430
+ `tar -xf #{@export_tar_file}`
431
+ end
432
+
433
+ Dir.chdir("#{@export_tar_dir}/#{@export_tar_prefix}") do
434
+ if File.exist?(@export_tar_file.gsub('.tar', '-repos.tar'))
435
+ `tar -xf #{@export_tar_file.gsub('.tar', '-repos.tar')}`
436
+ else
437
+ raise _("Export repos tar file is missing.")
438
+ end
439
+ end
440
+ end
441
+
442
+ def read_json
443
+ json_file = @export_tar_file.gsub('tar', 'json')
444
+ json_file = "#{@export_tar_dir}/#{@export_tar_prefix}/#{json_file}"
445
+ json_file = File.read(json_file)
446
+ JSON.parse(json_file)
447
+ end
448
+
449
+ def sync_repositories(repositories, organization_id)
450
+ repositories.each do |repo|
451
+ library_repos = index(
452
+ :repositories,
453
+ 'organization_id' => organization_id,
454
+ 'library' => true
455
+ )
456
+
457
+ library_repo = library_repos.select do |candidate_repo|
458
+ candidate_repo['label'] == repo['label']
459
+ end
460
+
461
+ library_repo = library_repo.first
462
+
463
+ if library_repo.nil?
464
+ msg = _("Unable to sync repositories, no library repository found for %s")
465
+ raise msg % repo['label']
466
+ end
467
+
468
+ synchronize(
469
+ library_repo['id'],
470
+ "file://#{@export_tar_dir}/#{@export_tar_prefix}/#{repo['relative_path']}"
471
+ )
472
+ end
473
+ end
474
+
475
+ def repos_units(repositories)
476
+ repositories.collect do |repo|
477
+ {
478
+ 'label' => repo['label'],
479
+ 'rpm_filenames' => repo['rpm_filenames']
480
+ }
481
+ end
482
+ end
483
+
484
+ def content_view(name, organization_id)
485
+ index(:content_views, 'name' => name, 'organization_id' => organization_id).first
486
+ end
487
+
488
+ def synchronize(id, source_url)
489
+ task_progress(call(:sync, :repositories, 'id' => id, 'source_url' => source_url))
490
+ end
491
+
492
+ def publish(id, major, minor, repos_units)
493
+ params = {'id' => id, 'major' => major, 'minor' => minor, 'repos_units' => repos_units}
494
+ task_progress(call(:publish, :content_views, params))
495
+ end
496
+ end
497
+
262
498
  autoload_subcommands
263
499
  end
264
500
  end
@@ -3,6 +3,10 @@ module HammerCLIKatello
3
3
  resource :errata
4
4
 
5
5
  class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ validate_repo_name_requires_product_options(:option_repository_name)
9
+
6
10
  output do
7
11
  field :id, _("ID")
8
12
  field :errata_id, _("Errata ID")
@@ -3,6 +3,10 @@ module HammerCLIKatello
3
3
  resource :file_units
4
4
 
5
5
  class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ validate_repo_name_requires_product_options(:option_repository_name)
9
+
6
10
  output do
7
11
  field :id, _("ID")
8
12
  field :name, _("Name")
@@ -12,15 +16,9 @@ module HammerCLIKatello
12
16
  validate_options do
13
17
  organization_options = [:option_organization_id, :option_organization_name,
14
18
  :option_organization_label]
15
- product_options = [:option_product_id, :option_product_name]
16
-
17
19
  if any(:option_product_name, :option_content_view_name).exist?
18
20
  any(*organization_options).required
19
21
  end
20
-
21
- if option(:option_repository_name).exist?
22
- any(*product_options).required
23
- end
24
22
  end
25
23
 
26
24
  build_options do |o|
@@ -76,7 +76,7 @@ module HammerCLIKatello
76
76
  create_search_options_without_katello_api(options, api.resource(:compute_resources), mode)
77
77
  end
78
78
 
79
- def create_image_search_options(options, mode = nil)
79
+ def create_images_search_options(options, mode = nil)
80
80
  create_search_options_without_katello_api(options, api.resource(:images), mode)
81
81
  end
82
82
  end
@@ -10,6 +10,8 @@ module HammerCLIKatello
10
10
  :file_unit => [s_name(_("File name to search by")),
11
11
  s("content_view_version_id", _("Content View Version ID")),
12
12
  s("repository_id", _("Repository ID"))],
13
+ :module_stream => [s_name(_("Module stream name to search by")),
14
+ s("repository_id", _("Repository ID"))],
13
15
  :gpg => [s_name(_("Gpg key name to search by"))],
14
16
  :host_collection => [s_name(_("Host collection name to search by"))],
15
17
  :lifecycle_environment => [s_name(_("Lifecycle environment name to search by"))],
@@ -0,0 +1,9 @@
1
+ module HammerCLIKatello
2
+ module LocalHelper
3
+ def parse_subcommand
4
+ return super if File.exist?('/usr/share/foreman')
5
+ raise "This command can only be run on the same server that Foreman is running on " \
6
+ "and cannot be run remotely."
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+ module HammerCLIKatello
2
+ class ModuleStreamCommand < HammerCLIKatello::Command
3
+ resource :module_streams
4
+
5
+ class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ desc "List module streams"
9
+
10
+ validate_repo_name_requires_product_options(:option_repository_name)
11
+
12
+ output do
13
+ field :id, _("ID")
14
+ field :name, _("Module Stream Name")
15
+ field :stream, _("Stream")
16
+ field :uuid, _("UUID")
17
+ field :version, _("Version")
18
+ field :arch, _("Architecture")
19
+ field :context, _("Context")
20
+ end
21
+
22
+ build_options do |o|
23
+ o.expand.including(:products)
24
+ end
25
+ end
26
+
27
+ class InfoCommand < HammerCLIKatello::InfoCommand
28
+ extend RepositoryScopedToProduct
29
+
30
+ validate_repo_name_requires_product_options(:option_repository_name)
31
+
32
+ output do
33
+ field :id, _("ID")
34
+ field :name, _("Module Stream Name")
35
+ field :stream, _("Stream")
36
+ field :uuid, _("UUID")
37
+ field :version, _("Version")
38
+ field :arch, _("Architecture")
39
+ field :context, _("Context")
40
+
41
+ collection :repositories, _("Repositories") do
42
+ field :id, _("ID")
43
+ field :name, _("Name")
44
+ field :label, _("Label")
45
+ end
46
+
47
+ collection :artifacts, _("Artifacts") do
48
+ field :id, _("ID")
49
+ field :name, _("Name")
50
+ end
51
+
52
+ collection :profiles, _("Profiles") do
53
+ field :id, _("ID")
54
+ field :name, _("Name")
55
+ collection :rpms, _("RPMs") do
56
+ field :id, _("ID")
57
+ field :name, _("Name")
58
+ end
59
+ end
60
+ end
61
+
62
+ build_options do |o|
63
+ o.expand.including(:products, :organizations)
64
+ end
65
+ end
66
+
67
+ autoload_subcommands
68
+ end
69
+ end
File without changes
@@ -3,6 +3,10 @@ module HammerCLIKatello
3
3
  resource :ostree_branches
4
4
 
5
5
  class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ validate_repo_name_requires_product_options(:option_repository_name)
9
+
6
10
  output do
7
11
  field :id, _("ID")
8
12
  field :name, _("Name")
@@ -3,6 +3,10 @@ module HammerCLIKatello
3
3
  resource :package_groups
4
4
 
5
5
  class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ validate_repo_name_requires_product_options(:option_repository_name)
9
+
6
10
  output do
7
11
  field :id, _("ID")
8
12
  field :name, _("Package Group Name")
@@ -3,6 +3,10 @@ module HammerCLIKatello
3
3
  resource :puppet_modules
4
4
 
5
5
  class ListCommand < HammerCLIKatello::ListCommand
6
+ extend RepositoryScopedToProduct
7
+
8
+ validate_repo_name_requires_product_options(:option_repository_name)
9
+
6
10
  output do
7
11
  field :id, _("ID")
8
12
  field :name, _("Name")
@@ -18,7 +18,9 @@ module HammerCLIKatello
18
18
 
19
19
  # rubocop:disable ClassLength
20
20
  class InfoCommand < HammerCLIKatello::InfoCommand
21
- include RepositoryScopedToProduct
21
+ extend RepositoryScopedToProduct
22
+
23
+ validate_repo_name_requires_product_options
22
24
 
23
25
  output do
24
26
  field :id, _("ID")
@@ -42,6 +44,8 @@ module HammerCLIKatello
42
44
  Fields::Field, :hide_blank => true
43
45
  field :docker_upstream_name, _("Upstream Repository Name"),
44
46
  Fields::Field, :hide_blank => true
47
+ field :docker_tags_whitelist, _("Container Image Tags Filter"),
48
+ Fields::List, :hide_blank => true
45
49
  field :container_repository_name, _("Container Repository Name"),
46
50
  Fields::Field, :hide_blank => true
47
51
  field :ignorable_content, _("Ignorable Content Units"), Fields::List, :hide_blank => true
@@ -81,6 +85,7 @@ module HammerCLIKatello
81
85
  field :docker_tag_total, _("Container Image Tags"), Fields::Field, :hide_blank => true
82
86
  field :ostree_branch_total, _("OSTree Branches"), Fields::Field, :hide_blank => true
83
87
  field :file_total, _("Files"), Fields::Field, :hide_blank => true
88
+ field :module_stream_total, _("Module Streams"), Fields::Field, :hide_blank => true
84
89
  end
85
90
  end
86
91
 
@@ -118,6 +123,7 @@ module HammerCLIKatello
118
123
  data["srpm_total"] = content_counts["srpm"]
119
124
  data["package_group_total"] = content_counts["package_group"]
120
125
  data["errata_total"] = content_counts["erratum"]
126
+ data["module_stream_total"] = content_counts["module_stream"]
121
127
  when "docker"
122
128
  data["docker_manifest_list_total"] = content_counts["docker_manifest_list"]
123
129
  data["docker_manifest_total"] = content_counts["docker_manifest"]
@@ -156,7 +162,9 @@ module HammerCLIKatello
156
162
 
157
163
  class SyncCommand < HammerCLIKatello::SingleResourceCommand
158
164
  include HammerCLIForemanTasks::Async
159
- include RepositoryScopedToProduct
165
+ extend RepositoryScopedToProduct
166
+
167
+ validate_repo_name_requires_product_options
160
168
 
161
169
  action :sync
162
170
  command_name "synchronize"
@@ -181,7 +189,9 @@ module HammerCLIKatello
181
189
  end
182
190
 
183
191
  class UpdateCommand < HammerCLIKatello::UpdateCommand
184
- include RepositoryScopedToProduct
192
+ extend RepositoryScopedToProduct
193
+
194
+ validate_repo_name_requires_product_options
185
195
  include OrganizationOptions
186
196
 
187
197
  success_message _("Repository updated.")
@@ -265,9 +275,10 @@ module HammerCLIKatello
265
275
  end
266
276
 
267
277
  class DeleteCommand < HammerCLIKatello::DeleteCommand
268
- include RepositoryScopedToProduct
278
+ extend RepositoryScopedToProduct
269
279
  include OrganizationOptions
270
280
 
281
+ validate_repo_name_requires_product_options
271
282
  success_message _("Repository deleted.")
272
283
  failure_message _("Could not delete the Repository")
273
284
 
@@ -278,9 +289,10 @@ module HammerCLIKatello
278
289
 
279
290
  # rubocop:disable ClassLength
280
291
  class UploadContentCommand < HammerCLIKatello::InfoCommand
281
- include RepositoryScopedToProduct
292
+ extend RepositoryScopedToProduct
282
293
  include HammerCLIForemanTasks::Helper
283
294
 
295
+ validate_repo_name_requires_product_options
284
296
  resource :repositories, :upload_content
285
297
  command_name "upload-content"
286
298
  CONTENT_CHUNK_SIZE = 2_500_000 # bytes to make sure it's lower than django's default 2621440
@@ -461,9 +473,10 @@ module HammerCLIKatello
461
473
  # rubocop:enable ClassLength
462
474
 
463
475
  class RemoveContentCommand < HammerCLIKatello::SingleResourceCommand
464
- include RepositoryScopedToProduct
476
+ extend RepositoryScopedToProduct
465
477
  include OrganizationOptions
466
478
 
479
+ validate_repo_name_requires_product_options
467
480
  action :remove_content
468
481
  command_name "remove-content"
469
482
  desc _("Remove content from a repository")
@@ -487,9 +500,10 @@ module HammerCLIKatello
487
500
 
488
501
  class ExportCommand < HammerCLIKatello::SingleResourceCommand
489
502
  include HammerCLIForemanTasks::Async
490
- include RepositoryScopedToProduct
491
503
  include OrganizationOptions
504
+ extend RepositoryScopedToProduct
492
505
 
506
+ validate_repo_name_requires_product_options
493
507
  action :export
494
508
  command_name "export"
495
509
  desc _("Export content from a repository to the configured directory")
@@ -1,8 +1,8 @@
1
1
  module HammerCLIKatello
2
2
  module RepositoryScopedToProduct
3
- def self.included(base)
4
- base.validate_options do
5
- any(:option_product_name, :option_product_id).required if option(:option_name).exist?
3
+ def validate_repo_name_requires_product_options(name_option = :option_name)
4
+ validate_options do
5
+ any(:option_product_name, :option_product_id).required if option(name_option).exist?
6
6
  end
7
7
  end
8
8
  end
@@ -4,6 +4,11 @@ module HammerCLIKatello
4
4
  module SearchOptionsCreators
5
5
  include HammerCLIKatello::ForemanSearchOptionsCreators
6
6
 
7
+ def create_module_streams_search_options(options, mode = nil)
8
+ create_search_options_without_katello_api(options, api.resource(:module_streams), mode)
9
+ .merge(create_search_options(options, api.resource(:module_streams), mode))
10
+ end
11
+
7
12
  def create_file_units_search_options(options, mode = nil)
8
13
  create_search_options_without_katello_api(options, api.resource(:file_units), mode)
9
14
  .merge(create_search_options(options, api.resource(:file_units), mode))
@@ -87,12 +92,15 @@ module HammerCLIKatello
87
92
  search_options
88
93
  end
89
94
 
90
- def create_search_options_with_katello_api(options, resource, _mode = nil)
95
+ def create_search_options_with_katello_api(options, resource, mode = nil)
91
96
  search_options = {}
92
97
  searchables(resource).each do |s|
93
98
  value = options[HammerCLI.option_accessor_name(s.name.to_s)]
94
- if value
99
+ values = options[HammerCLI.option_accessor_name(s.plural_name.to_s)]
100
+ if value && [:single, nil].include?(mode)
95
101
  search_options.update(s.name.to_s => value.to_s)
102
+ elsif values && [:multi, nil].include?(mode)
103
+ values.each { |v| search_options.update(s.name.to_s => v.to_s) }
96
104
  end
97
105
  end
98
106
  search_options