hammer_cli_katello 0.22.3 → 0.24.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hammer_cli_katello.rb +19 -2
  3. data/lib/hammer_cli_katello/content_export.rb +72 -0
  4. data/lib/hammer_cli_katello/content_export_complete.rb +25 -0
  5. data/lib/hammer_cli_katello/content_export_helper.rb +172 -0
  6. data/lib/hammer_cli_katello/content_export_incremental.rb +25 -0
  7. data/lib/hammer_cli_katello/content_import.rb +63 -0
  8. data/lib/hammer_cli_katello/content_view.rb +3 -1
  9. data/lib/hammer_cli_katello/deb_package.rb +66 -0
  10. data/lib/hammer_cli_katello/host.rb +5 -0
  11. data/lib/hammer_cli_katello/host_deb.rb +20 -0
  12. data/lib/hammer_cli_katello/ping.rb +10 -3
  13. data/lib/hammer_cli_katello/repository.rb +60 -1
  14. data/lib/hammer_cli_katello/version.rb +1 -1
  15. data/test/data/3.16/foreman_api.json +1 -1
  16. data/test/data/3.17/foreman_api.json +1 -1
  17. data/test/data/3.18/foreman_api.json +1 -0
  18. data/test/functional/content_export/complete/library_test.rb +155 -0
  19. data/test/functional/content_export/complete/version_test.rb +185 -0
  20. data/test/functional/content_export/content_export_helpers.rb +21 -0
  21. data/test/functional/content_export/generate_metadata_test.rb +64 -0
  22. data/test/functional/content_export/incremental/library_test.rb +172 -0
  23. data/test/functional/content_export/incremental/version_test.rb +236 -0
  24. data/test/functional/content_export/list_test.rb +34 -0
  25. data/test/functional/content_import/library_test.rb +85 -0
  26. data/test/functional/content_import/metadata.json +1 -0
  27. data/test/functional/content_import/version_test.rb +85 -0
  28. data/test/functional/ping_test.rb +2 -1
  29. data/test/functional/repository/info_test.rb +133 -23
  30. data/test/functional/repository/update_test.rb +41 -1
  31. data/test/test_helper.rb +1 -1
  32. metadata +31 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3d63fdac09ed3e0edb26ab298ed436a2f8ed95d1b6295239cb67e99b3481af3
4
- data.tar.gz: 18f682373e69a6094aaaf5961d5d3209e57064e181384bfba5d0371dff59ce00
3
+ metadata.gz: 3a90c77802499a72d618883d73162f061b8465d838be44c8df27e3d79d2fc316
4
+ data.tar.gz: d4cd08a9eb8fae1437bad8d9adaba03fb5a71cd2c770b5af6500312fb497283c
5
5
  SHA512:
6
- metadata.gz: '09bd2f414bded08ee849413060c911bc30ca740a59981fab30f13cca31ef6fb221ded816c7f62006f9ae142adf9d5d5ad1de5edc73afcf6032c52d1b963226ff'
7
- data.tar.gz: fb1e742aac09aa4c097fb034cd4697f7f70f1f0535ce373c18af963263a627e17b8f9d7f1c4d9b470998147167b00534978e36eeb2f32e95d9c55d1d7dadc9a9
6
+ metadata.gz: 3aa81078857f074f4c15104e67a31ca9b85ba05d95510b2805114df31955972acd4795078ae3128849568d2f1c3e1e19d274307ac97d7cc8391edc1f05cd44b9
7
+ data.tar.gz: ce940d980543120e2cf86a0374fb61e11c20ce37ee06c2ff381b98da2c5731c6adcb4cac0b59bd80d945233b2589d13889859097a910e838117403ee002137c5
@@ -31,6 +31,7 @@ module HammerCLIKatello
31
31
  require 'hammer_cli_katello/local_helper'
32
32
  require 'hammer_cli_katello/apipie_helper'
33
33
  require 'hammer_cli_katello/cv_import_export_helper'
34
+ require 'hammer_cli_katello/content_export_helper'
34
35
 
35
36
  # commands
36
37
  HammerCLI::MainCommand.lazy_subcommand("activation-key", _("Manipulate activation keys"),
@@ -53,8 +54,7 @@ module HammerCLIKatello
53
54
  )
54
55
 
55
56
  HammerCLI::MainCommand.lazy_subcommand("content-credentials",
56
- _("Manipulate content credentials (i.e. GPG Keys)' \
57
- 'on the server"),
57
+ _("Manipulate content credentials on the server"),
58
58
  'HammerCLIKatello::ContentCredentialCommand',
59
59
  'hammer_cli_katello/content_credential'
60
60
  )
@@ -117,6 +117,11 @@ module HammerCLIKatello
117
117
  'hammer_cli_katello/package'
118
118
  )
119
119
 
120
+ HammerCLI::MainCommand.lazy_subcommand("deb-package", _("Manipulate deb packages"),
121
+ 'HammerCLIKatello::DebPackageCommand',
122
+ 'hammer_cli_katello/deb_package'
123
+ )
124
+
120
125
  HammerCLI::MainCommand.lazy_subcommand("package-group", _("Manipulate package groups"),
121
126
  'HammerCLIKatello::PackageGroupCommand',
122
127
  'hammer_cli_katello/package_group'
@@ -137,6 +142,18 @@ module HammerCLIKatello
137
142
  'hammer_cli_katello/file'
138
143
  )
139
144
 
145
+ HammerCLI::MainCommand.lazy_subcommand("content-export",
146
+ _("Prepare content for export to a disconnected Katello"),
147
+ 'HammerCLIKatello::ContentExport',
148
+ 'hammer_cli_katello/content_export'
149
+ )
150
+
151
+ HammerCLI::MainCommand.lazy_subcommand("content-import",
152
+ _("Import content from an upstream archive."),
153
+ 'HammerCLIKatello::ContentImport',
154
+ 'hammer_cli_katello/content_import'
155
+ )
156
+
140
157
  HammerCLI::MainCommand.lazy_subcommand("module-stream", _("View Module Streams"),
141
158
  'HammerCLIKatello::ModuleStreamCommand',
142
159
  'hammer_cli_katello/module_stream'
@@ -0,0 +1,72 @@
1
+ require 'hammer_cli_katello/content_export_complete'
2
+ require 'hammer_cli_katello/content_export_incremental'
3
+
4
+ module HammerCLIKatello
5
+ class ContentExport < HammerCLIKatello::Command
6
+ desc "Prepare content for export to a disconnected Katello"
7
+ resource :content_exports
8
+
9
+ class GenerateMetadataCommand < HammerCLIKatello::Command
10
+ desc _("Writes export metadata to disk for use by the importing Katello. This command "\
11
+ + "only needs to be used if the export was performed asynchronously "\
12
+ + "or if the metadata was lost")
13
+
14
+ command_name 'generate-metadata'
15
+
16
+ include ContentExportHelper
17
+
18
+ option "--task-id", "TASK_ID",
19
+ _("Generate metadata based on output of the specified export task"),
20
+ :attribute_name => :option_task_id,
21
+ :required => false
22
+
23
+ option "--id", "ID",
24
+ _("Generate metadata based on specified export history"),
25
+ :attribute_name => :option_export_id,
26
+ :required => false
27
+
28
+ def execute
29
+ export_history = if option_task_id
30
+ export_task = reload_task(option_task_id)
31
+ fetch_export_history_from_task(export_task)
32
+ else
33
+ fetch_export_history(option_export_id)
34
+ end
35
+
36
+ unless export_history
37
+ raise _("No export history was found. Verify the value given for "\
38
+ + "--task-id or --id")
39
+ end
40
+
41
+ generate_metadata_json(export_history)
42
+
43
+ HammerCLI::EX_OK
44
+ end
45
+ end
46
+
47
+ class ListCommand < HammerCLIKatello::ListCommand
48
+ desc "View content view export histories"
49
+ output do
50
+ field :id, _('ID')
51
+ field :destination_server, _('Destination Server')
52
+ field :path, _('Path')
53
+ field :content_view_version, _('Content View Version')
54
+ field :content_view_version_id, _('Content View Version ID')
55
+ field :created_at, _('Created at')
56
+ field :updated_at, _('Updated at'), Fields::Field, :hide_blank => true
57
+ end
58
+
59
+ build_options
60
+ end
61
+
62
+ autoload_subcommands
63
+
64
+ subcommand HammerCLIKatello::ContentExportComplete.command_name,
65
+ HammerCLIKatello::ContentExportComplete.desc,
66
+ HammerCLIKatello::ContentExportComplete
67
+
68
+ subcommand HammerCLIKatello::ContentExportIncremental.command_name,
69
+ HammerCLIKatello::ContentExportIncremental.desc,
70
+ HammerCLIKatello::ContentExportIncremental
71
+ end
72
+ end
@@ -0,0 +1,25 @@
1
+ module HammerCLIKatello
2
+ class ContentExportComplete < HammerCLIKatello::Command
3
+ desc "Prepare content for a full export to a disconnected Katello"
4
+ resource :content_exports
5
+ command_name 'complete'
6
+
7
+ class VersionCommand < HammerCLIKatello::SingleResourceCommand
8
+ desc _('Performs a full export a content view version')
9
+ command_name "version"
10
+
11
+ include HammerCLIForemanTasks::Async
12
+ include ContentExportHelper
13
+ end
14
+
15
+ class LibraryCommand < HammerCLIKatello::SingleResourceCommand
16
+ desc _("Performs a full export of the organization's library environment")
17
+ command_name "library"
18
+
19
+ include HammerCLIForemanTasks::Async
20
+ include ContentExportHelper
21
+ end
22
+
23
+ autoload_subcommands
24
+ end
25
+ end
@@ -0,0 +1,172 @@
1
+ require 'hammer_cli_katello/repository'
2
+ # rubocop:disable ModuleLength
3
+ module HammerCLIKatello
4
+ module ContentExportHelper
5
+ include ApipieHelper
6
+
7
+ def execute
8
+ warn_unexportable_repositories
9
+ response = super
10
+ if option_async?
11
+ output.print_message _("Once the task completes the export metadata must be generated "\
12
+ + "with the command:")
13
+ output.print_message(" hammer content-export generate-metadata --task-id #{@task['id']}")
14
+ HammerCLI::EX_OK
15
+ elsif response != HammerCLI::EX_OK
16
+ response
17
+ else
18
+ export_history = fetch_export_history_from_task(reload_task(@task))
19
+ if export_history
20
+ generate_metadata_json(export_history)
21
+ HammerCLI::EX_OK
22
+ else
23
+ output.print_error _("Could not fetch the export history")
24
+ HammerCLI::EX_CANTCREAT
25
+ end
26
+ end
27
+ end
28
+
29
+ def send_request
30
+ @task = super
31
+ end
32
+
33
+ def reload_task(task)
34
+ task_id = if task.is_a? Hash
35
+ task['id']
36
+ else
37
+ task
38
+ end
39
+ show(:foreman_tasks, id: task_id)
40
+ end
41
+
42
+ def fetch_export_history(export_history_id)
43
+ resource.call(:index, :id => export_history_id)["results"].first if export_history_id
44
+ end
45
+
46
+ def fetch_export_history_from_task(task)
47
+ # checking this here implies the task object was loaded recently
48
+ if %w(error warning).include?(task['result'])
49
+ raise _("Can not fetch export history from an unfinished task")
50
+ end
51
+
52
+ export_history_id = task.dig('output', 'export_history_id')
53
+ fetch_export_history(export_history_id)
54
+ end
55
+
56
+ def generate_metadata_json(export_history)
57
+ metadata_json = export_history["metadata"].to_json
58
+ begin
59
+ metadata_path = "#{export_history['path']}/metadata.json"
60
+ File.write(metadata_path, metadata_json)
61
+ output.print_message _("Generated #{metadata_path}")
62
+ rescue SystemCallError
63
+ filename = "metadata-#{export_history['id']}.json"
64
+ File.write(filename, metadata_json)
65
+ output.print_message _("Unable to access/write to '#{export_history['path']}'. "\
66
+ "Generated '#{Dir.pwd}/#{filename}' instead. "\
67
+ "This file is necessary to perform an import.")
68
+ end
69
+ end
70
+
71
+ def version_command?
72
+ self.class.command_name.first.to_sym == :version
73
+ end
74
+
75
+ def fetch_repositories
76
+ repo_options = {
77
+ library: true,
78
+ content_type: 'yum',
79
+ search: 'download_policy != immediate'
80
+ }
81
+ if version_command?
82
+ repo_options[:content_view_version_id] = resolver.content_view_version_id(options)
83
+ else
84
+ repo_options[:organization_id] = options["option_organization_id"]
85
+ end
86
+ index(:repositories, repo_options)
87
+ end
88
+
89
+ def warn_unexportable_repositories
90
+ repos = fetch_repositories
91
+ unless repos.empty?
92
+ if version_command?
93
+ output.print_message _("NOTE: Unable to fully export this version because"\
94
+ " it contains repositories without the 'immediate' download policy."\
95
+ " Update the download policy and sync affected repositories."\
96
+ " Once synced republish the content view"\
97
+ " and export the generated version.")
98
+ else
99
+ output.print_message _("NOTE: Unable to fully export this organization's library because"\
100
+ " it contains repositories without the 'immediate' download policy."\
101
+ " Update the download policy and sync affected"\
102
+ " repositories to include them in the export.")
103
+ end
104
+ output.print_message _("Use the following command to update the "\
105
+ "download policy of these repositories.")
106
+ output.print_message "hammer repository update --id=<REPOSITORY_ID> "\
107
+ "--download-policy='immediate'"
108
+ output.print_message ""
109
+ print_record(::HammerCLIKatello::Repository::ListCommand.output_definition, repos)
110
+ exit(HammerCLI::EX_SOFTWARE) if option_fail_on_missing_content?
111
+ end
112
+ end
113
+
114
+ def self.included(base)
115
+ if base.command_name.first.to_sym == :version
116
+ setup_version(base)
117
+ elsif base.command_name.first.to_sym == :library
118
+ setup_library(base)
119
+ end
120
+ end
121
+
122
+ def self.setup_library(base)
123
+ base.action(:library)
124
+ base.success_message _("Library environment is being exported in task %{id}.")
125
+ base.failure_message _("Could not export the library")
126
+ base.option "--fail-on-missing-content", :flag,
127
+ _("Fails if any of the repositories belonging"\
128
+ " to this organization are unexportable.")
129
+
130
+ base.build_options do |o|
131
+ o.expand(:all).including(:organizations)
132
+ end
133
+ end
134
+
135
+ def self.setup_version(base)
136
+ base.action(:version)
137
+ base.option "--fail-on-missing-content", :flag,
138
+ _("Fails if any of the repositories belonging"\
139
+ " to this version are unexportable.")
140
+
141
+ base.option "--version", "VERSION", _("Filter versions by version number."),
142
+ :attribute_name => :option_version,
143
+ :required => false
144
+
145
+ base.build_options do |o|
146
+ o.expand(:all).including(:content_views, :organizations)
147
+ end
148
+
149
+ base.validate_options do
150
+ unless option(:option_id).exist?
151
+ any(:option_id, :option_content_view_name, :option_content_view_id).required
152
+ option(:option_version).required
153
+ unless option(:option_content_view_id).exist?
154
+ any(:option_organization_id, :option_organization_name, \
155
+ :option_organization_label).required
156
+ end
157
+ end
158
+ end
159
+
160
+ base.success_message _("Content view version is being exported in task %{id}.")
161
+ base.failure_message _("Could not export the content view version")
162
+
163
+ base.class_eval do
164
+ def request_params
165
+ super.tap do |opts|
166
+ opts["id"] = resolver.content_view_version_id(options)
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,25 @@
1
+ module HammerCLIKatello
2
+ class ContentExportIncremental < HammerCLIKatello::Command
3
+ desc "Prepare content for an incremental export to a disconnected Katello"
4
+ resource :content_export_incrementals
5
+ command_name 'incremental'
6
+
7
+ class VersionCommand < HammerCLIKatello::SingleResourceCommand
8
+ desc _('Performs an incremental export of a content view version')
9
+ command_name "version"
10
+
11
+ include HammerCLIForemanTasks::Async
12
+ include ContentExportHelper
13
+ end
14
+
15
+ class LibraryCommand < HammerCLIKatello::SingleResourceCommand
16
+ desc _("Performs an incremental export of the organization's library environment")
17
+ command_name "library"
18
+
19
+ include HammerCLIForemanTasks::Async
20
+ include ContentExportHelper
21
+ end
22
+
23
+ autoload_subcommands
24
+ end
25
+ end
@@ -0,0 +1,63 @@
1
+ module HammerCLIKatello
2
+ class ContentImport < HammerCLIKatello::Command
3
+ desc "Import content from a content archive"
4
+ resource :content_imports
5
+
6
+ module ContentImportCommon
7
+ def self.included(base)
8
+ base.option "--metadata-file",
9
+ "METADATA_FILE", _("Location of the metadata.json file. "\
10
+ "This is not required if the metadata.json file"\
11
+ " is already in the archive directory."),
12
+ :attribute_name => :option_metadata_file,
13
+ :required => false
14
+
15
+ base.build_options do |o|
16
+ o.expand(:all).including(:content_views, :organizations).except(:metadata)
17
+ end
18
+
19
+ base.validate_options do
20
+ option(:option_path).required
21
+
22
+ metadata_file = option(:option_metadata_file).value ||
23
+ File.join(option(:option_path).value, "metadata.json")
24
+ unless File.exist?(metadata_file)
25
+ msg = _("Unable to find '#{metadata_file}'. "\
26
+ "If the metadata.json file is at a different location "\
27
+ "provide it to the --metadata-file option ")
28
+ raise HammerCLI::Options::Validators::ValidationError, msg
29
+ end
30
+ end
31
+ base.success_message _("Archive is being imported in task %{id}.")
32
+ base.failure_message _("Could not import the archive.")
33
+ end
34
+
35
+ def request_params
36
+ super.tap do |opts|
37
+ metadata_file = option_metadata_file || File.join(option_path, "metadata.json")
38
+ opts["metadata"] = JSON.parse(File.read(metadata_file))
39
+ end
40
+ end
41
+ end
42
+
43
+ class VersionCommand < HammerCLIKatello::SingleResourceCommand
44
+ desc _('Imports a content archive to a content view version')
45
+ action :version
46
+ command_name "version"
47
+
48
+ include HammerCLIForemanTasks::Async
49
+ include ContentImportCommon
50
+ end
51
+
52
+ class LibraryCommand < HammerCLIKatello::SingleResourceCommand
53
+ desc _("Imports a content archive to an organization's library lifecycle environment")
54
+ action :library
55
+ command_name "library"
56
+
57
+ include HammerCLIForemanTasks::Async
58
+ include ContentImportCommon
59
+ end
60
+
61
+ autoload_subcommands
62
+ end
63
+ end
@@ -106,10 +106,12 @@ module HammerCLIKatello
106
106
  failure_message _("Could not create the content view")
107
107
 
108
108
  option ["--composite"], :flag, _("Create a composite content view")
109
-
109
+ option ["--import-only"], :flag, _("Designate this Content View for "\
110
+ "importing from upstream servers only.")
110
111
  def request_params
111
112
  super.tap do |opts|
112
113
  opts['composite'] = option_composite? || false
114
+ opts['import_only'] = option_import_only? || false
113
115
  end
114
116
  end
115
117
 
@@ -0,0 +1,66 @@
1
+ module HammerCLIKatello
2
+ class DebPackageCommand < HammerCLIKatello::Command
3
+ resource :debs
4
+
5
+ class ListCommand < HammerCLIKatello::ListCommand
6
+ extend_with(HammerCLIKatello::CommandExtensions::LifecycleEnvironment.new)
7
+ include LifecycleEnvironmentNameMapping
8
+
9
+ output do
10
+ field :id, _("ID")
11
+ field :filename, _("Filename")
12
+ end
13
+
14
+ validate_options :before, 'IdResolution' do
15
+ organization_options = [:option_organization_id, :option_organization_name, \
16
+ :option_organization_label]
17
+ product_options = [:option_product_id, :option_product_name]
18
+ content_view_options = [:option_content_view_id, :option_content_view_name]
19
+
20
+ if option(:option_product_name).exist? || option(:option_content_view_name).exist?
21
+ any(*organization_options).required
22
+ end
23
+
24
+ if option(:option_repository_name).exist?
25
+ any(*product_options).required
26
+ end
27
+
28
+ if option(:option_content_view_version_version).exist?
29
+ any(*content_view_options).required
30
+ end
31
+
32
+ if any(*content_view_options).exist?
33
+ any(:option_content_view_version_id,
34
+ :option_content_view_version_version,
35
+ :option_environment_id,
36
+ :option_environment_name).required
37
+ end
38
+ end
39
+ build_options do |o|
40
+ o.expand.including(:products, :content_views)
41
+ end
42
+ end
43
+
44
+ class InfoCommand < HammerCLIKatello::InfoCommand
45
+ output do
46
+ field :id, _("ID")
47
+ field :pulp_id, _("Pulp ID")
48
+ field :uuid, _("UUID")
49
+ field :name, _("Name")
50
+ field :version, _("Version")
51
+ field :checksum, _("checksum")
52
+ field :arch, _("Architecture")
53
+ field :nav, _("Nav")
54
+ field :nva, _("Nva")
55
+ field :filename, _("Filename")
56
+ field :hosts_available_count, _("Available Host Count")
57
+ field :hosts_applicable_count, _("Applicable Host Count")
58
+ field :description, _("Description")
59
+ end
60
+
61
+ build_options
62
+ end
63
+
64
+ autoload_subcommands
65
+ end
66
+ end