hammer_cli_katello 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hammer_cli_katello.rb +1 -0
- data/lib/hammer_cli_katello/content_view.rb +1 -1
- data/lib/hammer_cli_katello/filter.rb +19 -0
- data/lib/hammer_cli_katello/filter_rule.rb +0 -10
- data/lib/hammer_cli_katello/host_extensions.rb +2 -0
- data/lib/hammer_cli_katello/id_name_options_validator.rb +73 -0
- data/lib/hammer_cli_katello/package.rb +2 -0
- data/lib/hammer_cli_katello/repository.rb +17 -5
- data/lib/hammer_cli_katello/version.rb +1 -1
- data/test/functional/content_view/create_test.rb +0 -3
- data/test/functional/content_view/filter/delete_test.rb +93 -0
- data/test/functional/content_view/filter/info_test.rb +92 -0
- data/test/functional/content_view/filter/list_test.rb +98 -0
- data/test/functional/content_view/filter/update_test.rb +93 -0
- data/test/functional/filter_rule/create_test.rb +0 -79
- data/test/functional/host/extensions/data/host.json +4 -2
- data/test/functional/host/extensions/info_test.rb +3 -1
- data/test/functional/lifecycle_environment/create_test.rb +14 -0
- data/test/functional/lifecycle_environment/list_test.rb +38 -0
- data/test/functional/lifecycle_environment/update_test.rb +14 -0
- data/test/functional/organization/organization_helpers.rb +2 -2
- data/test/functional/package/list_test.rb +48 -0
- data/test/functional/repository/delete_test.rb +101 -0
- data/test/functional/repository/upload_test.rb +43 -0
- data/test/unit/id_name_options_validator_test.rb +96 -0
- metadata +26 -13
- data/test/functional/filter_rule/delete_test.rb +0 -104
- data/test/functional/filter_rule/info_test.rb +0 -104
- data/test/functional/filter_rule/list_test.rb +0 -91
- data/test/functional/filter_rule/update_test.rb +0 -104
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ee67377eb8631f27bc3ac6fb8893aa4f3e19cd6
|
4
|
+
data.tar.gz: 3aa751e158e61a5e65854d7423c280ff9be55493
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8af86a66650da765757af0c2ea262f08bbdeadfd27f88e5bb8dcac35f9318f7badfd7885bb0d844010d860bf636de433ffd032402de81e3774d635e4b6f86d76
|
7
|
+
data.tar.gz: b7db6c9f52337875421b12022cb1a2ea4dddfce2e88707c5035636395cfa8cfbe70ad1ef71430d2bf0dc6446e0cd22cfaf5eacfba16e6d58ec903125a80d78c5
|
data/lib/hammer_cli_katello.rb
CHANGED
@@ -25,6 +25,7 @@ module HammerCLIKatello
|
|
25
25
|
require "hammer_cli_katello/version"
|
26
26
|
require 'hammer_cli_katello/id_resolver'
|
27
27
|
require 'hammer_cli_katello/capsule'
|
28
|
+
require 'hammer_cli_katello/id_name_options_validator'
|
28
29
|
|
29
30
|
# commands
|
30
31
|
HammerCLI::MainCommand.lazy_subcommand("activation-key", _("Manipulate activation keys."),
|
@@ -207,7 +207,7 @@ module HammerCLIKatello
|
|
207
207
|
success_message _("Content view objects are being removed task %{id}")
|
208
208
|
failure_message _("Could not remove objects from content view")
|
209
209
|
|
210
|
-
build_options :without => %w(content_view_version_ids
|
210
|
+
build_options :without => %w(content_view_version_ids environment_ids)
|
211
211
|
end
|
212
212
|
|
213
213
|
class AddContentViewVersionCommand < HammerCLIKatello::AddAssociatedCommand
|
@@ -7,6 +7,9 @@ module HammerCLIKatello
|
|
7
7
|
desc 'View and manage filters'
|
8
8
|
|
9
9
|
class ListCommand < HammerCLIKatello::ListCommand
|
10
|
+
include OrganizationOptions
|
11
|
+
extend IdNameOptionsValidator
|
12
|
+
|
10
13
|
output do
|
11
14
|
field :id, _("Filter ID")
|
12
15
|
field :name, _("Name")
|
@@ -15,9 +18,13 @@ module HammerCLIKatello
|
|
15
18
|
end
|
16
19
|
|
17
20
|
build_options
|
21
|
+
validate_id_or_name_with_parent :content_view
|
18
22
|
end
|
19
23
|
|
20
24
|
class InfoCommand < HammerCLIKatello::InfoCommand
|
25
|
+
include OrganizationOptions
|
26
|
+
extend IdNameOptionsValidator
|
27
|
+
|
21
28
|
output do
|
22
29
|
field :id, _("Filter ID")
|
23
30
|
field :name, _("Name")
|
@@ -47,6 +54,8 @@ module HammerCLIKatello
|
|
47
54
|
end
|
48
55
|
|
49
56
|
build_options :without => [:content_view_id]
|
57
|
+
validate_id_or_name_with_parent parent: :content_view
|
58
|
+
validate_id_or_name_with_parent :content_view, required: false
|
50
59
|
end
|
51
60
|
|
52
61
|
class CreateCommand < HammerCLIKatello::CreateCommand
|
@@ -68,17 +77,27 @@ module HammerCLIKatello
|
|
68
77
|
end
|
69
78
|
|
70
79
|
class UpdateCommand < HammerCLIKatello::UpdateCommand
|
80
|
+
include OrganizationOptions
|
81
|
+
extend IdNameOptionsValidator
|
82
|
+
|
71
83
|
success_message _("Filter updated")
|
72
84
|
failure_message _("Could not update the filter")
|
73
85
|
|
74
86
|
build_options :without => [:content_view_id]
|
87
|
+
validate_id_or_name_with_parent parent: :content_view
|
88
|
+
validate_id_or_name_with_parent :content_view, required: false
|
75
89
|
end
|
76
90
|
|
77
91
|
class DeleteCommand < HammerCLIKatello::DeleteCommand
|
92
|
+
include OrganizationOptions
|
93
|
+
extend IdNameOptionsValidator
|
94
|
+
|
78
95
|
success_message _("Filter deleted")
|
79
96
|
failure_message _("Could not delete the filter")
|
80
97
|
|
81
98
|
build_options :without => [:content_view_id]
|
99
|
+
validate_id_or_name_with_parent parent: :content_view
|
100
|
+
validate_id_or_name_with_parent :content_view, required: false
|
82
101
|
end
|
83
102
|
|
84
103
|
HammerCLIKatello::AssociatingCommands::Repository.extend_command(self)
|
@@ -5,8 +5,6 @@ module HammerCLIKatello
|
|
5
5
|
desc 'View and manage filter rules'
|
6
6
|
|
7
7
|
class ListCommand < HammerCLIKatello::ListCommand
|
8
|
-
include OrganizationOptions
|
9
|
-
|
10
8
|
output do
|
11
9
|
field :id, _("Rule ID")
|
12
10
|
field :content_view_filter_id, _("Filter ID")
|
@@ -24,8 +22,6 @@ module HammerCLIKatello
|
|
24
22
|
end
|
25
23
|
|
26
24
|
class InfoCommand < HammerCLIKatello::InfoCommand
|
27
|
-
include OrganizationOptions
|
28
|
-
|
29
25
|
output do
|
30
26
|
field :id, _("Rule ID")
|
31
27
|
field :content_view_filter_id, _("Filter ID")
|
@@ -47,8 +43,6 @@ module HammerCLIKatello
|
|
47
43
|
end
|
48
44
|
|
49
45
|
class CreateCommand < HammerCLIKatello::CreateCommand
|
50
|
-
include OrganizationOptions
|
51
|
-
|
52
46
|
success_message _("Filter rule created")
|
53
47
|
failure_message _("Could not create the filter rule")
|
54
48
|
|
@@ -64,8 +58,6 @@ module HammerCLIKatello
|
|
64
58
|
end
|
65
59
|
|
66
60
|
class UpdateCommand < HammerCLIKatello::UpdateCommand
|
67
|
-
include OrganizationOptions
|
68
|
-
|
69
61
|
success_message _("Filter rule updated")
|
70
62
|
failure_message _("Could not update the filter rule")
|
71
63
|
|
@@ -73,8 +65,6 @@ module HammerCLIKatello
|
|
73
65
|
end
|
74
66
|
|
75
67
|
class DeleteCommand < HammerCLIKatello::DeleteCommand
|
76
|
-
include OrganizationOptions
|
77
|
-
|
78
68
|
success_message _("Filter rule deleted")
|
79
69
|
failure_message _("Could not delete the filter rule")
|
80
70
|
|
@@ -21,6 +21,8 @@ module HammerCLIKatello
|
|
21
21
|
from :content_facet_attributes do
|
22
22
|
field :content_view_name, _('Content View')
|
23
23
|
field :lifecycle_environment_name, _('Lifecycle Environment')
|
24
|
+
field :applicable_package_count, _('Applicable Packages')
|
25
|
+
field :upgradable_package_count, _('Upgradable Packages')
|
24
26
|
|
25
27
|
label _('Applicable Errata') do
|
26
28
|
from :errata_counts do
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module HammerCLIKatello
|
2
|
+
module IdNameOptionsValidator
|
3
|
+
# This is a method that requires:
|
4
|
+
# 1. either name or id has been supplied
|
5
|
+
# 2. if name is supplied, parent id/name/etc is also required
|
6
|
+
#
|
7
|
+
# Normally the parent will be organization as with products, content views,
|
8
|
+
# etc but this could also apply to repos for example whose names are unique
|
9
|
+
# per product
|
10
|
+
#
|
11
|
+
# Some examples:
|
12
|
+
#
|
13
|
+
# validate_id_or_name_with_parent
|
14
|
+
# validate_id_or_name_with_parent :content_view
|
15
|
+
# validate_id_or_name_with_parent :repository, parent: 'product', required: false
|
16
|
+
# validate_id_or_name_with_parent :content_view, parent: {organization: ['id', 'name']}
|
17
|
+
def validate_id_or_name_with_parent(record_name = nil, parent: 'organization', required: true)
|
18
|
+
child_options = IdNameOptionsValidator.build_child_options(record_name)
|
19
|
+
parent_options = IdNameOptionsValidator.build_parent_options(parent)
|
20
|
+
|
21
|
+
validate_options do
|
22
|
+
any(*child_options).required if required
|
23
|
+
|
24
|
+
if (name_option = child_options.detect { |opt| opt.end_with?('_name') }) &&
|
25
|
+
option(name_option).exist?
|
26
|
+
any(*parent_options).required
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# This method simply checks that either id or name is supplied
|
32
|
+
#
|
33
|
+
# Some examples:
|
34
|
+
#
|
35
|
+
# # checks for a --id or --name option
|
36
|
+
# validate_id_or_name
|
37
|
+
# # checks for --content-view-id or --content-view-name
|
38
|
+
# validate_id_or_name :content_view
|
39
|
+
def validate_id_or_name(record_name = nil)
|
40
|
+
child_options = IdNameOptionsValidator.build_child_options(record_name)
|
41
|
+
|
42
|
+
validate_options do
|
43
|
+
any(*child_options).required
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.build_child_options(record_name)
|
48
|
+
if record_name.nil?
|
49
|
+
%w(option_id option_name)
|
50
|
+
else
|
51
|
+
IdNameOptionsValidator.build_options(record_name, %w(id name))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.build_parent_options(parent)
|
56
|
+
if parent.is_a?(String) || parent.is_a?(Symbol)
|
57
|
+
opts = parent.to_s == 'organization' ? %w(id name label) : %w(id name)
|
58
|
+
elsif parent.is_a?(Hash)
|
59
|
+
parent, opts = parent.first.to_a
|
60
|
+
else
|
61
|
+
raise "Unkown parent class: #{parent.class} for #{parent}"
|
62
|
+
end
|
63
|
+
|
64
|
+
IdNameOptionsValidator.build_options(parent, opts)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.build_options(record_name, options)
|
68
|
+
options.map do |opt|
|
69
|
+
"option_#{record_name}_#{opt}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -172,6 +172,7 @@ module HammerCLIKatello
|
|
172
172
|
|
173
173
|
class DeleteCommand < HammerCLIKatello::DeleteCommand
|
174
174
|
include RepositoryScopedToProduct
|
175
|
+
include OrganizationOptions
|
175
176
|
|
176
177
|
success_message _("Repository deleted")
|
177
178
|
failure_message _("Could not delete the Repository")
|
@@ -194,8 +195,10 @@ module HammerCLIKatello
|
|
194
195
|
|
195
196
|
if File.directory?(fullpath)
|
196
197
|
Dir["#{fullpath}/*"]
|
197
|
-
|
198
|
+
elsif File.exist?(fullpath)
|
198
199
|
[fullpath]
|
200
|
+
else
|
201
|
+
Dir[fullpath]
|
199
202
|
end
|
200
203
|
end
|
201
204
|
end
|
@@ -206,7 +209,14 @@ module HammerCLIKatello
|
|
206
209
|
|
207
210
|
def execute
|
208
211
|
@failure = false
|
209
|
-
|
212
|
+
files = option_content
|
213
|
+
|
214
|
+
if files.length.zero?
|
215
|
+
output.print_error _("Could not find any files matching PATH")
|
216
|
+
return HammerCLI::EX_NOINPUT
|
217
|
+
end
|
218
|
+
|
219
|
+
files.each do |file_path|
|
210
220
|
File.open(file_path, 'rb') { |file| upload_file file }
|
211
221
|
end
|
212
222
|
|
@@ -223,7 +233,9 @@ module HammerCLIKatello
|
|
223
233
|
build_options(:without => [:content]) do |o|
|
224
234
|
o.expand.including(:products, :organizations)
|
225
235
|
end
|
226
|
-
option "--path", "PATH", _("Upload file
|
236
|
+
option "--path", "PATH", _("Upload file, directory of files, or glob of files " \
|
237
|
+
"as content for a repository.\n" \
|
238
|
+
"Globs must be escaped by single or double quotes."),
|
227
239
|
:attribute_name => :option_content,
|
228
240
|
:required => true, :format => BinaryPath.new
|
229
241
|
|
@@ -251,8 +263,8 @@ module HammerCLIKatello
|
|
251
263
|
print_message _("Successfully uploaded file '%s'.") % filename
|
252
264
|
rescue
|
253
265
|
@failure = true
|
254
|
-
|
255
|
-
|
266
|
+
output.print_error _("Failed to upload file '%s' to repository. Please check "\
|
267
|
+
"the file and try again.") % filename
|
256
268
|
ensure
|
257
269
|
content_upload_resource.call(:destroy, :repository_id => get_identifier, :id => upload_id)
|
258
270
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), '../content_view_helpers')
|
3
|
+
require File.join(File.dirname(__FILE__), '../../organization/organization_helpers')
|
4
|
+
|
5
|
+
module HammerCLIForeman
|
6
|
+
describe DeleteCommand do
|
7
|
+
include ContentViewHelpers
|
8
|
+
include OrganizationHelpers
|
9
|
+
|
10
|
+
before do
|
11
|
+
@cmd = %w(content-view filter delete)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'accepts filter id' do
|
15
|
+
params = ['--id=1']
|
16
|
+
|
17
|
+
api_expects(:content_view_filters, :destroy) do |par|
|
18
|
+
par['id'] == '1'
|
19
|
+
end
|
20
|
+
|
21
|
+
run_cmd(@cmd + params)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'accepts filter name, content view name, and org name' do
|
25
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization=pkd']
|
26
|
+
|
27
|
+
expect_organization_search('pkd', 1)
|
28
|
+
expect_content_view_search(1, 'darkly', 1)
|
29
|
+
expect_content_view_search(1, 'darkly', 1) # redmine #15930
|
30
|
+
|
31
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
32
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
33
|
+
end
|
34
|
+
ex.returns(index_response([{'id' => '1'}]))
|
35
|
+
|
36
|
+
api_expects(:content_view_filters, :destroy) do |par|
|
37
|
+
par['id'] == '1'
|
38
|
+
end
|
39
|
+
|
40
|
+
run_cmd(@cmd + params)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'accepts filter name, content view name, and org label' do
|
44
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization-label=pkd']
|
45
|
+
|
46
|
+
expect_organization_search('pkd', 1, field: 'label')
|
47
|
+
expect_content_view_search(1, 'darkly', 1)
|
48
|
+
expect_content_view_search(1, 'darkly', 1) # redmine #15930
|
49
|
+
|
50
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
51
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
52
|
+
end
|
53
|
+
ex.returns(index_response([{'id' => '1'}]))
|
54
|
+
|
55
|
+
api_expects(:content_view_filters, :destroy) do |par|
|
56
|
+
par['id'] == '1'
|
57
|
+
end
|
58
|
+
|
59
|
+
run_cmd(@cmd + params)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'accepts filter name, content view name, and org id' do
|
63
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization-id=1']
|
64
|
+
|
65
|
+
expect_content_view_search('1', 'darkly', 1)
|
66
|
+
expect_content_view_search('1', 'darkly', 1) # redmine #15930
|
67
|
+
|
68
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
69
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
70
|
+
end
|
71
|
+
ex.returns(index_response([{'id' => '1'}]))
|
72
|
+
|
73
|
+
api_expects(:content_view_filters, :destroy) do |par|
|
74
|
+
par['id'] == '1'
|
75
|
+
end
|
76
|
+
|
77
|
+
run_cmd(@cmd + params)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'requires organization name or id if content view name is supplied' do
|
81
|
+
params = ["--name=high-castle", "--content-view=grasshopper"]
|
82
|
+
expected_result = usage_error_result(
|
83
|
+
@cmd,
|
84
|
+
'At least one of options --organization-id, --organization, --organization-label ' \
|
85
|
+
'is required',
|
86
|
+
'Could not delete the filter'
|
87
|
+
)
|
88
|
+
api_expects_no_call
|
89
|
+
result = run_cmd(@cmd + params)
|
90
|
+
assert_cmd(expected_result, result)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
require File.join(File.dirname(__FILE__), '../content_view_helpers')
|
3
|
+
require File.join(File.dirname(__FILE__), '../../organization/organization_helpers')
|
4
|
+
|
5
|
+
module HammerCLIForeman
|
6
|
+
describe InfoCommand do
|
7
|
+
include ContentViewHelpers
|
8
|
+
include OrganizationHelpers
|
9
|
+
|
10
|
+
before do
|
11
|
+
@cmd = %w(content-view filter info)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'accepts filter id' do
|
15
|
+
params = ['--id=1']
|
16
|
+
|
17
|
+
api_expects(:content_view_filters, :show) do |par|
|
18
|
+
par['id'] == '1'
|
19
|
+
end
|
20
|
+
|
21
|
+
run_cmd(@cmd + params)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'accepts filter name, content view name, and org name' do
|
25
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization=pkd']
|
26
|
+
|
27
|
+
expect_organization_search('pkd', 1)
|
28
|
+
expect_content_view_search(1, 'darkly', 1)
|
29
|
+
expect_content_view_search(1, 'darkly', 1) # redmine #15930
|
30
|
+
|
31
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
32
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
33
|
+
end
|
34
|
+
ex.returns(index_response([{'id' => '1'}]))
|
35
|
+
|
36
|
+
api_expects(:content_view_filters, :show) do |par|
|
37
|
+
par['id'] == '1'
|
38
|
+
end
|
39
|
+
|
40
|
+
run_cmd(@cmd + params)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'accepts filter name, content view name, and org label' do
|
44
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization-label=pkd']
|
45
|
+
|
46
|
+
expect_organization_search('pkd', 1, field: 'label')
|
47
|
+
expect_content_view_search(1, 'darkly', 1)
|
48
|
+
expect_content_view_search(1, 'darkly', 1) # redmine #15930
|
49
|
+
|
50
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
51
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
52
|
+
end
|
53
|
+
ex.returns(index_response([{'id' => '1'}]))
|
54
|
+
|
55
|
+
api_expects(:content_view_filters, :show) do |par|
|
56
|
+
par['id'] == '1'
|
57
|
+
end
|
58
|
+
|
59
|
+
run_cmd(@cmd + params)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'accepts filter name, content view name, and org id' do
|
63
|
+
params = ['--name=scanner', '--content-view=darkly', '--organization-id=1']
|
64
|
+
|
65
|
+
expect_content_view_search('1', 'darkly', 1)
|
66
|
+
expect_content_view_search('1', 'darkly', 1) # redmine #15930
|
67
|
+
|
68
|
+
ex = api_expects(:content_view_filters, :index, 'Content view filters list') do |par|
|
69
|
+
par['content_view_id'] == 1 && par['name'] == 'scanner'
|
70
|
+
end
|
71
|
+
ex.returns(index_response([{'id' => '1'}]))
|
72
|
+
|
73
|
+
api_expects(:content_view_filters, :show) do |par|
|
74
|
+
par['id'] == '1'
|
75
|
+
end
|
76
|
+
|
77
|
+
run_cmd(@cmd + params)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'requires organization name or id if content view name is supplied' do
|
81
|
+
params = ["--name=high-castle", "--content-view=grasshopper"]
|
82
|
+
expected_result = usage_error_result(
|
83
|
+
@cmd,
|
84
|
+
'At least one of options --organization-id, --organization, --organization-label ' \
|
85
|
+
'is required'
|
86
|
+
)
|
87
|
+
api_expects_no_call
|
88
|
+
result = run_cmd(@cmd + params)
|
89
|
+
assert_cmd(expected_result, result)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|