hammer_cli_katello 0.23.1 → 0.24.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hammer_cli_katello.rb +14 -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 +181 -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/host_traces.rb +17 -0
  10. data/lib/hammer_cli_katello/id_resolver.rb +5 -1
  11. data/lib/hammer_cli_katello/ping.rb +10 -3
  12. data/lib/hammer_cli_katello/version.rb +1 -1
  13. data/test/data/3.18/foreman_api.json +1 -0
  14. data/test/functional/content_export/complete/library_test.rb +155 -0
  15. data/test/functional/content_export/complete/version_test.rb +217 -0
  16. data/test/functional/content_export/content_export_helpers.rb +26 -0
  17. data/test/functional/content_export/generate_metadata_test.rb +64 -0
  18. data/test/functional/content_export/incremental/library_test.rb +172 -0
  19. data/test/functional/content_export/incremental/version_test.rb +268 -0
  20. data/test/functional/content_export/list_test.rb +64 -0
  21. data/test/functional/content_import/library_test.rb +85 -0
  22. data/test/functional/content_import/metadata.json +1 -0
  23. data/test/functional/content_import/version_test.rb +85 -0
  24. data/test/functional/content_view/content_view_helpers.rb +3 -1
  25. data/test/functional/host/extensions/update_test.rb +0 -1
  26. data/test/functional/host/traces/resolve_test.rb +31 -0
  27. data/test/functional/lifecycle_environment/lifecycle_environment_helpers.rb +1 -1
  28. data/test/functional/ping_test.rb +2 -1
  29. data/test/functional/search_helpers.rb +11 -0
  30. data/test/test_helper.rb +1 -1
  31. metadata +32 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39b7d013b69ccff473c384efe07fbc1c1574033c074e685be65723f5e3d79156
4
- data.tar.gz: 9ba014e8f0a515eddfbb66d507483fa8f81b8873c5e670eca78755989bc1f40d
3
+ metadata.gz: 3966349f8fac0df348af893168e4eb594d765834eeef7e973fe465cf78755331
4
+ data.tar.gz: 51541df551c787282da8367983c6a29543b529e20192c098169b5d0d1c1bc203
5
5
  SHA512:
6
- metadata.gz: 32c3e1f7dc2aa8fa32ceba935d7229c7b628bdf9429f6ed1fa036e818d3cca44bfa47d5d2319e7b8b16354688302f6743168fca59aa62c4a956f9ba4206fe74c
7
- data.tar.gz: d270942a73c21fa9e996f1e0457d82b8e4abc866ddeed5d201d017febfbf9272640144aeacc260387550e8e8e22b36fac80b33b2e7b3d93fad87ff98ee465886
6
+ metadata.gz: 5ed98c8abdee101d12324fdc9605c568f9adff0e3dae32d59941ac1d5ec8ebfa2d50826297d7826cff39ca2fb9b47707b356eb5e09618b2dc971bd5852cc0c50
7
+ data.tar.gz: 1c4f11a142861744f6f4ee0c618927d460c84e581ece723d76dc18ea44b90949b8afd1aa53747aa5d3307311814ece3d6cdf8f2ba94cbb019d7f63f395b39d16
@@ -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
  )
@@ -142,6 +142,18 @@ module HammerCLIKatello
142
142
  'hammer_cli_katello/file'
143
143
  )
144
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
+
145
157
  HammerCLI::MainCommand.lazy_subcommand("module-stream", _("View Module Streams"),
146
158
  'HammerCLIKatello::ModuleStreamCommand',
147
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,181 @@
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
+ setup_version_options(base)
138
+ base.success_message _("Content view version is being exported in task %{id}.")
139
+ base.failure_message _("Could not export the content view version")
140
+
141
+ base.extend_with(
142
+ HammerCLIKatello::CommandExtensions::LifecycleEnvironments.new(only: :option_sources)
143
+ )
144
+ base.include(LifecycleEnvironmentNameMapping)
145
+
146
+ base.class_eval do
147
+ def request_params
148
+ super.tap do |opts|
149
+ opts["id"] = resolver.content_view_version_id(options)
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ def self.setup_version_options(base)
156
+ base.option "--fail-on-missing-content", :flag,
157
+ _("Fails if any of the repositories belonging"\
158
+ " to this version are unexportable.")
159
+
160
+ base.option "--version", "VERSION", _("Filter versions by version number."),
161
+ :attribute_name => :option_version,
162
+ :required => false
163
+
164
+ base.build_options do |o|
165
+ o.expand(:all).including(:content_views, :organizations, :environments)
166
+ o.without(:environment_ids, :environment_id)
167
+ end
168
+
169
+ base.validate_options do
170
+ unless option(:option_id).exist?
171
+ any(:option_id, :option_content_view_name, :option_content_view_id).required
172
+ any(:option_version, :option_environment_id, :option_environment_name).required
173
+ unless option(:option_content_view_id).exist?
174
+ any(:option_organization_id, :option_organization_name, \
175
+ :option_organization_label).required
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ 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
 
@@ -14,6 +14,23 @@ module HammerCLIKatello
14
14
  end
15
15
  build_options
16
16
  end
17
+
18
+ class ResolveCommand < HammerCLIKatello::SingleResourceCommand
19
+ include HammerCLIForemanTasks::Async
20
+ resource :host_tracer, :resolve
21
+ command_name "resolve"
22
+
23
+ success_message _("Traces are being resolved with task %{id}.")
24
+ failure_message _("Could not resolve traces")
25
+
26
+ validate_options do
27
+ option(:option_trace_ids).required
28
+ option(:option_host_id).required
29
+ end
30
+
31
+ build_options
32
+ end
33
+
17
34
  autoload_subcommands
18
35
  end
19
36
  end