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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hammer_cli_katello.rb +1 -0
  3. data/lib/hammer_cli_katello/content_view.rb +1 -1
  4. data/lib/hammer_cli_katello/filter.rb +19 -0
  5. data/lib/hammer_cli_katello/filter_rule.rb +0 -10
  6. data/lib/hammer_cli_katello/host_extensions.rb +2 -0
  7. data/lib/hammer_cli_katello/id_name_options_validator.rb +73 -0
  8. data/lib/hammer_cli_katello/package.rb +2 -0
  9. data/lib/hammer_cli_katello/repository.rb +17 -5
  10. data/lib/hammer_cli_katello/version.rb +1 -1
  11. data/test/functional/content_view/create_test.rb +0 -3
  12. data/test/functional/content_view/filter/delete_test.rb +93 -0
  13. data/test/functional/content_view/filter/info_test.rb +92 -0
  14. data/test/functional/content_view/filter/list_test.rb +98 -0
  15. data/test/functional/content_view/filter/update_test.rb +93 -0
  16. data/test/functional/filter_rule/create_test.rb +0 -79
  17. data/test/functional/host/extensions/data/host.json +4 -2
  18. data/test/functional/host/extensions/info_test.rb +3 -1
  19. data/test/functional/lifecycle_environment/create_test.rb +14 -0
  20. data/test/functional/lifecycle_environment/list_test.rb +38 -0
  21. data/test/functional/lifecycle_environment/update_test.rb +14 -0
  22. data/test/functional/organization/organization_helpers.rb +2 -2
  23. data/test/functional/package/list_test.rb +48 -0
  24. data/test/functional/repository/delete_test.rb +101 -0
  25. data/test/functional/repository/upload_test.rb +43 -0
  26. data/test/unit/id_name_options_validator_test.rb +96 -0
  27. metadata +26 -13
  28. data/test/functional/filter_rule/delete_test.rb +0 -104
  29. data/test/functional/filter_rule/info_test.rb +0 -104
  30. data/test/functional/filter_rule/list_test.rb +0 -91
  31. 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: d7777a95f65993c11aafcdf3e93bd4e62e05a71c
4
- data.tar.gz: 10751c77ff38e730bd28edf8a393387ae5ac4551
3
+ metadata.gz: 8ee67377eb8631f27bc3ac6fb8893aa4f3e19cd6
4
+ data.tar.gz: 3aa751e158e61a5e65854d7423c280ff9be55493
5
5
  SHA512:
6
- metadata.gz: 483606e3bfe638f29d98185eb2dc38f2a0704f3e16de14cc4e89aff942f1ad8ea7f5fd60a7939ea17a91a57b56449e3dd3618c9e2e009b92d048dc8774872342
7
- data.tar.gz: b043a18647859bba0dadfa79103085f23a3de85a2fb332cff57b082ed20efd3b1b86a69b705148110f0028d7b682dade57ef6fce691b27c681b147831b15be18
6
+ metadata.gz: 8af86a66650da765757af0c2ea262f08bbdeadfd27f88e5bb8dcac35f9318f7badfd7885bb0d844010d860bf636de433ffd032402de81e3774d635e4b6f86d76
7
+ data.tar.gz: b7db6c9f52337875421b12022cb1a2ea4dddfce2e88707c5035636395cfa8cfbe70ad1ef71430d2bf0dc6446e0cd22cfaf5eacfba16e6d58ec903125a80d78c5
@@ -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 environment_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
@@ -9,6 +9,8 @@ module HammerCLIKatello
9
9
  end
10
10
 
11
11
  build_options do |o|
12
+ o.without(:repository_id)
13
+ o.expand.except(:repositories)
12
14
  o.expand.including(:products, :organizations, :content_views)
13
15
  end
14
16
  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
- else
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
- option_content.each do |file_path|
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 or directory of files as content for a repository"),
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
- print_message _("Failed to upload file '%s' to repository. Please check "\
255
- "the file and try again.") % filename
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
@@ -1,5 +1,5 @@
1
1
  module HammerCLIKatello
2
2
  def self.version
3
- @version ||= Gem::Version.new('0.1.3')
3
+ @version ||= Gem::Version.new('0.2.0')
4
4
  end
5
5
  end
@@ -1,8 +1,5 @@
1
1
  require_relative '../test_helper'
2
2
 
3
- # Workaround for issue #14289
4
- require 'hammer_cli_katello/content_view_puppet_module'
5
-
6
3
  describe 'content-view create' do
7
4
  before do
8
5
  @cmd = %w(content-view create)
@@ -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