inspec 0.14.8 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -2
  3. data/bin/inspec +3 -4
  4. data/examples/inheritance/README.md +19 -0
  5. data/examples/inheritance/controls/example.rb +11 -0
  6. data/examples/inheritance/inspec.yml +10 -0
  7. data/lib/bundles/inspec-compliance/cli.rb +1 -4
  8. data/lib/bundles/inspec-supermarket/cli.rb +1 -4
  9. data/lib/inspec/dsl.rb +48 -55
  10. data/lib/inspec/profile.rb +6 -2
  11. data/lib/inspec/profile_context.rb +21 -8
  12. data/lib/inspec/runner.rb +17 -12
  13. data/lib/inspec/runner_rspec.rb +1 -0
  14. data/lib/inspec/version.rb +1 -1
  15. data/lib/resources/apache.rb +20 -18
  16. data/lib/resources/apache_conf.rb +92 -90
  17. data/lib/resources/apt.rb +92 -90
  18. data/lib/resources/audit_policy.rb +35 -33
  19. data/lib/resources/auditd_conf.rb +41 -39
  20. data/lib/resources/auditd_rules.rb +155 -153
  21. data/lib/resources/bond.rb +1 -1
  22. data/lib/resources/bridge.rb +97 -95
  23. data/lib/resources/command.rb +47 -45
  24. data/lib/resources/csv.rb +23 -21
  25. data/lib/resources/directory.rb +1 -1
  26. data/lib/resources/etc_group.rb +116 -114
  27. data/lib/resources/file.rb +1 -1
  28. data/lib/resources/gem.rb +39 -37
  29. data/lib/resources/group.rb +100 -98
  30. data/lib/resources/host.rb +103 -101
  31. data/lib/resources/inetd_conf.rb +42 -40
  32. data/lib/resources/ini.rb +15 -13
  33. data/lib/resources/interface.rb +106 -104
  34. data/lib/resources/iptables.rb +36 -34
  35. data/lib/resources/json.rb +64 -62
  36. data/lib/resources/kernel_module.rb +30 -28
  37. data/lib/resources/kernel_parameter.rb +44 -42
  38. data/lib/resources/limits_conf.rb +41 -39
  39. data/lib/resources/login_def.rb +38 -36
  40. data/lib/resources/mount.rb +43 -41
  41. data/lib/resources/mysql.rb +67 -65
  42. data/lib/resources/mysql_conf.rb +89 -87
  43. data/lib/resources/mysql_session.rb +46 -44
  44. data/lib/resources/npm.rb +35 -33
  45. data/lib/resources/ntp_conf.rb +44 -42
  46. data/lib/resources/oneget.rb +46 -44
  47. data/lib/resources/os.rb +22 -20
  48. data/lib/resources/os_env.rb +47 -45
  49. data/lib/resources/package.rb +213 -211
  50. data/lib/resources/parse_config.rb +59 -57
  51. data/lib/resources/passwd.rb +89 -87
  52. data/lib/resources/pip.rb +60 -58
  53. data/lib/resources/port.rb +352 -350
  54. data/lib/resources/postgres.rb +26 -24
  55. data/lib/resources/postgres_conf.rb +66 -64
  56. data/lib/resources/postgres_session.rb +47 -45
  57. data/lib/resources/processes.rb +56 -54
  58. data/lib/resources/registry_key.rb +150 -148
  59. data/lib/resources/script.rb +30 -28
  60. data/lib/resources/security_policy.rb +56 -54
  61. data/lib/resources/service.rb +638 -636
  62. data/lib/resources/shadow.rb +98 -96
  63. data/lib/resources/ssh_conf.rb +58 -56
  64. data/lib/resources/user.rb +363 -361
  65. data/lib/resources/windows_feature.rb +46 -44
  66. data/lib/resources/xinetd.rb +111 -109
  67. data/lib/resources/yaml.rb +16 -14
  68. data/lib/resources/yum.rb +107 -105
  69. data/lib/utils/base_cli.rb +18 -0
  70. data/test/helper.rb +2 -2
  71. data/test/unit/profile_context_test.rb +1 -1
  72. data/test/unit/resources/file_test.rb +1 -1
  73. data/test/unit/resources/mount_test.rb +1 -1
  74. metadata +5 -2
@@ -27,57 +27,59 @@
27
27
  # "Installed": false,
28
28
  # "InstallState": 0
29
29
  # }
30
- class WindowsFeature < Inspec.resource(1)
31
- name 'windows_feature'
32
- desc 'Use the windows_feature InSpec audit resource to test features on Microsoft Windows.'
33
- example "
34
- describe windows_feature('dhcp') do
35
- it { should be_installed }
36
- end
37
- "
30
+ module Inspec::Resources
31
+ class WindowsFeature < Inspec.resource(1)
32
+ name 'windows_feature'
33
+ desc 'Use the windows_feature InSpec audit resource to test features on Microsoft Windows.'
34
+ example "
35
+ describe windows_feature('dhcp') do
36
+ it { should be_installed }
37
+ end
38
+ "
38
39
 
39
- def initialize(feature)
40
- @feature = feature
41
- @cache = nil
40
+ def initialize(feature)
41
+ @feature = feature
42
+ @cache = nil
42
43
 
43
- # verify that this resource is only supported on Windows
44
- return skip_resource 'The `windows_feature` resource is not supported on your OS.' if inspec.os[:family] != 'windows'
45
- end
44
+ # verify that this resource is only supported on Windows
45
+ return skip_resource 'The `windows_feature` resource is not supported on your OS.' if inspec.os[:family] != 'windows'
46
+ end
46
47
 
47
- # returns true if the package is installed
48
- def installed?(_provider = nil, _version = nil)
49
- info[:installed] == true
50
- end
48
+ # returns true if the package is installed
49
+ def installed?(_provider = nil, _version = nil)
50
+ info[:installed] == true
51
+ end
51
52
 
52
- # returns the package description
53
- def info
54
- return @cache if !@cache.nil?
55
- features_cmd = "Get-WindowsFeature | Where-Object {$_.Name -eq '#{@feature}' -or $_.DisplayName -eq '#{@feature}'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json"
56
- cmd = inspec.command(features_cmd)
53
+ # returns the package description
54
+ def info
55
+ return @cache if !@cache.nil?
56
+ features_cmd = "Get-WindowsFeature | Where-Object {$_.Name -eq '#{@feature}' -or $_.DisplayName -eq '#{@feature}'} | Select-Object -Property Name,DisplayName,Description,Installed,InstallState | ConvertTo-Json"
57
+ cmd = inspec.command(features_cmd)
57
58
 
58
- @cache = {
59
- name: @feature,
60
- type: 'windows-feature',
61
- }
59
+ @cache = {
60
+ name: @feature,
61
+ type: 'windows-feature',
62
+ }
62
63
 
63
- # cannot rely on exit code for now, successful command returns exit code 1
64
- # return nil if cmd.exit_status != 0
65
- # try to parse json
66
- begin
67
- params = JSON.parse(cmd.stdout)
68
- rescue JSON::ParserError => _e
69
- return @cache
70
- end
64
+ # cannot rely on exit code for now, successful command returns exit code 1
65
+ # return nil if cmd.exit_status != 0
66
+ # try to parse json
67
+ begin
68
+ params = JSON.parse(cmd.stdout)
69
+ rescue JSON::ParserError => _e
70
+ return @cache
71
+ end
71
72
 
72
- @cache = {
73
- name: params['Name'],
74
- description: params['Description'],
75
- installed: params['Installed'],
76
- type: 'windows-feature',
77
- }
78
- end
73
+ @cache = {
74
+ name: params['Name'],
75
+ description: params['Description'],
76
+ installed: params['Installed'],
77
+ type: 'windows-feature',
78
+ }
79
+ end
79
80
 
80
- def to_s
81
- "Windows Feature '#{@feature}'"
81
+ def to_s
82
+ "Windows Feature '#{@feature}'"
83
+ end
82
84
  end
83
85
  end
@@ -4,139 +4,141 @@
4
4
 
5
5
  require 'utils/parser'
6
6
 
7
- class XinetdConf < Inspec.resource(1) # rubocop:disable Metrics/ClassLength
8
- name 'xinetd_conf'
9
- desc 'Xinetd services configuration.'
10
- example "
11
- describe xinetd_conf.services('chargen') do
12
- its('socket_types') { should include 'dgram' }
13
- end
7
+ module Inspec::Resources
8
+ class XinetdConf < Inspec.resource(1) # rubocop:disable Metrics/ClassLength
9
+ name 'xinetd_conf'
10
+ desc 'Xinetd services configuration.'
11
+ example "
12
+ describe xinetd_conf.services('chargen') do
13
+ its('socket_types') { should include 'dgram' }
14
+ end
14
15
 
15
- describe xinetd_conf.services('chargen').socket_types('dgram') do
16
- it { should be_disabled }
17
- end
18
- "
16
+ describe xinetd_conf.services('chargen').socket_types('dgram') do
17
+ it { should be_disabled }
18
+ end
19
+ "
19
20
 
20
- include XinetdParser
21
+ include XinetdParser
21
22
 
22
- def initialize(conf_path = '/etc/xinetd.conf', opts = {})
23
- @conf_path = conf_path
24
- @params = opts[:params] unless opts[:params].nil?
25
- @filters = opts[:filters] || ''
26
- @contents = {}
27
- end
23
+ def initialize(conf_path = '/etc/xinetd.conf', opts = {})
24
+ @conf_path = conf_path
25
+ @params = opts[:params] unless opts[:params].nil?
26
+ @filters = opts[:filters] || ''
27
+ @contents = {}
28
+ end
28
29
 
29
- def to_s
30
- "Xinetd config #{@conf_path}"
31
- end
30
+ def to_s
31
+ "Xinetd config #{@conf_path}"
32
+ end
32
33
 
33
- def services(condition = nil)
34
- condition.nil? ? params['services'].keys : filter(service: condition)
35
- end
34
+ def services(condition = nil)
35
+ condition.nil? ? params['services'].keys : filter(service: condition)
36
+ end
36
37
 
37
- def ids(condition = nil)
38
- condition.nil? ? services_field('id') : filter(id: condition)
39
- end
38
+ def ids(condition = nil)
39
+ condition.nil? ? services_field('id') : filter(id: condition)
40
+ end
40
41
 
41
- def socket_types(condition = nil)
42
- condition.nil? ? services_field('socket_type') : filter(socket_type: condition)
43
- end
42
+ def socket_types(condition = nil)
43
+ condition.nil? ? services_field('socket_type') : filter(socket_type: condition)
44
+ end
44
45
 
45
- def types(condition = nil)
46
- condition.nil? ? services_field('type') : filter(type: condition)
47
- end
46
+ def types(condition = nil)
47
+ condition.nil? ? services_field('type') : filter(type: condition)
48
+ end
48
49
 
49
- def wait(condition = nil)
50
- condition.nil? ? services_field('wait') : filter(wait: condition)
51
- end
50
+ def wait(condition = nil)
51
+ condition.nil? ? services_field('wait') : filter(wait: condition)
52
+ end
52
53
 
53
- def disabled?
54
- filter(disable: 'no').services.empty?
55
- end
54
+ def disabled?
55
+ filter(disable: 'no').services.empty?
56
+ end
56
57
 
57
- def enabled?
58
- filter(disable: 'yes').services.empty?
59
- end
58
+ def enabled?
59
+ filter(disable: 'yes').services.empty?
60
+ end
60
61
 
61
- def params
62
- return @params if defined?(@params)
63
- return @params = {} if read_content.nil?
64
- flat_params = parse_xinetd(read_content)
65
- @params = { 'services' => {} }
66
- flat_params.each do |k, v|
67
- name = k[/^service (.+)$/, 1]
68
- if name.nil?
69
- @params[k] = v
70
- else
71
- @params['services'][name] = v
62
+ def params
63
+ return @params if defined?(@params)
64
+ return @params = {} if read_content.nil?
65
+ flat_params = parse_xinetd(read_content)
66
+ @params = { 'services' => {} }
67
+ flat_params.each do |k, v|
68
+ name = k[/^service (.+)$/, 1]
69
+ if name.nil?
70
+ @params[k] = v
71
+ else
72
+ @params['services'][name] = v
73
+ end
72
74
  end
75
+ @params
73
76
  end
74
- @params
75
- end
76
77
 
77
- def filter(conditions = {})
78
- res = params.dup
79
- filters = ''
80
- conditions.each do |k, v|
81
- v = v.to_s if v.is_a? Integer
82
- filters += " #{k} = #{v.inspect}"
83
- res['services'] = filter_by(res['services'], k.to_s, v)
78
+ def filter(conditions = {})
79
+ res = params.dup
80
+ filters = ''
81
+ conditions.each do |k, v|
82
+ v = v.to_s if v.is_a? Integer
83
+ filters += " #{k} = #{v.inspect}"
84
+ res['services'] = filter_by(res['services'], k.to_s, v)
85
+ end
86
+ XinetdConf.new(@conf_path, params: res, filters: filters)
84
87
  end
85
- XinetdConf.new(@conf_path, params: res, filters: filters)
86
- end
87
88
 
88
- private
89
+ private
89
90
 
90
- # Retrieve the provided field from all configured services.
91
- #
92
- # @param [String] field name, e.g. `socket_type`
93
- # @return [Array[String]] all values of this field across services
94
- def services_field(field)
95
- params['services'].values.compact.flatten
96
- .map { |x| x.params[field] }.flatten.compact
97
- end
98
-
99
- def match_condition(sth, condition)
100
- case sth
101
- # this does Regex-matching as well as string comparison
102
- when condition
103
- true
104
- else
105
- false
91
+ # Retrieve the provided field from all configured services.
92
+ #
93
+ # @param [String] field name, e.g. `socket_type`
94
+ # @return [Array[String]] all values of this field across services
95
+ def services_field(field)
96
+ params['services'].values.compact.flatten
97
+ .map { |x| x.params[field] }.flatten.compact
106
98
  end
107
- end
108
99
 
109
- # Filter services by a criteria. This allows for search queries for
110
- # certain values.
111
- #
112
- # @param [Hash] service collection
113
- # @param [String] search key you want to query
114
- # @param [Any] search value that the key should match
115
- # @return [Hash] filtered service collection
116
- def filter_by(services, k, v)
117
- if k == 'service'
118
- return Hash[services.find_all { |name, _| match_condition(v, name) }]
100
+ def match_condition(sth, condition)
101
+ case sth
102
+ # this does Regex-matching as well as string comparison
103
+ when condition
104
+ true
105
+ else
106
+ false
107
+ end
119
108
  end
120
- Hash[services.map { |name, service_arr|
121
- found = service_arr.find_all { |service|
122
- match_condition(service.params[k], v)
123
- }
124
- found.empty? ? nil : [name, found]
125
- }.compact]
126
- end
127
109
 
128
- def read_content(path = @conf_path)
129
- return @contents[path] if @contents.key?(path)
130
- file = inspec.file(path)
131
- if !file.file?
132
- return skip_resource "Can't find file \"#{path}\""
110
+ # Filter services by a criteria. This allows for search queries for
111
+ # certain values.
112
+ #
113
+ # @param [Hash] service collection
114
+ # @param [String] search key you want to query
115
+ # @param [Any] search value that the key should match
116
+ # @return [Hash] filtered service collection
117
+ def filter_by(services, k, v)
118
+ if k == 'service'
119
+ return Hash[services.find_all { |name, _| match_condition(v, name) }]
120
+ end
121
+ Hash[services.map { |name, service_arr|
122
+ found = service_arr.find_all { |service|
123
+ match_condition(service.params[k], v)
124
+ }
125
+ found.empty? ? nil : [name, found]
126
+ }.compact]
133
127
  end
134
128
 
135
- @contents[path] = file.content
136
- if @contents[path].empty? && file.size > 0
137
- return skip_resource "Can't read file \"#{path}\""
138
- end
129
+ def read_content(path = @conf_path)
130
+ return @contents[path] if @contents.key?(path)
131
+ file = inspec.file(path)
132
+ if !file.file?
133
+ return skip_resource "Can't find file \"#{path}\""
134
+ end
135
+
136
+ @contents[path] = file.content
137
+ if @contents[path].empty? && file.size > 0
138
+ return skip_resource "Can't read file \"#{path}\""
139
+ end
139
140
 
140
- @contents[path]
141
+ @contents[path]
142
+ end
141
143
  end
142
144
  end
@@ -9,21 +9,23 @@ require 'yaml'
9
9
  # describe yaml('.kitchen.yaml') do
10
10
  # its('driver.name') { should eq('vagrant') }
11
11
  # end
12
- class YamlConfig < JsonConfig
13
- name 'yaml'
14
- desc 'Use the yaml InSpec audit resource to test configuration data in a YAML file.'
15
- example "
16
- describe yaml do
17
- its('name') { should eq 'foo' }
18
- end
19
- "
12
+ module Inspec::Resources
13
+ class YamlConfig < JsonConfig
14
+ name 'yaml'
15
+ desc 'Use the yaml InSpec audit resource to test configuration data in a YAML file.'
16
+ example "
17
+ describe yaml do
18
+ its('name') { should eq 'foo' }
19
+ end
20
+ "
20
21
 
21
- # override file load and parse hash from yaml
22
- def parse(content)
23
- YAML.load(content)
24
- end
22
+ # override file load and parse hash from yaml
23
+ def parse(content)
24
+ YAML.load(content)
25
+ end
25
26
 
26
- def to_s
27
- "YAML #{@path}"
27
+ def to_s
28
+ "YAML #{@path}"
29
+ end
28
30
  end
29
31
  end
data/lib/resources/yum.rb CHANGED
@@ -30,132 +30,134 @@ require 'resources/file'
30
30
  # it { should be_enabled }
31
31
  # end
32
32
 
33
- class Yum < Inspec.resource(1)
34
- name 'yum'
35
- desc 'Use the yum InSpec audit resource to test packages in the Yum repository.'
36
- example "
37
- describe yum.repo('name') do
38
- it { should exist }
39
- it { should be_enabled }
40
- end
41
- "
42
-
43
- # returns all repositories
44
- # works as following:
45
- # search for Repo-id
46
- # parse data in hashmap
47
- # store data in object
48
- # until \n
49
- def repositories
50
- return @cache if defined?(@cache)
51
- # parse the repository data from yum
52
- # we cannot use -C, because this is not reliable and may lead to errors
53
- @command_result = inspec.command('yum -v repolist all')
54
- @content = @command_result.stdout
55
- @cache = []
56
- repo = {}
57
- in_repo = false
58
- @content.each_line do |line|
59
- # detect repo start
60
- in_repo = true if line =~ /^\s*Repo-id\s*:\s*(.*)\b/
61
- # detect repo end
62
- if line == "\n" && in_repo
63
- in_repo = false
64
- @cache.push(repo)
65
- repo = {}
33
+ module Inspec::Resources
34
+ class Yum < Inspec.resource(1)
35
+ name 'yum'
36
+ desc 'Use the yum InSpec audit resource to test packages in the Yum repository.'
37
+ example "
38
+ describe yum.repo('name') do
39
+ it { should exist }
40
+ it { should be_enabled }
66
41
  end
67
- # parse repo content
68
- if in_repo == true
69
- val = /^\s*([^:]*?)\s*:\s*(.*?)\s*$/.match(line)
70
- repo[repo_key(strip(val[1]))] = strip(val[2])
42
+ "
43
+
44
+ # returns all repositories
45
+ # works as following:
46
+ # search for Repo-id
47
+ # parse data in hashmap
48
+ # store data in object
49
+ # until \n
50
+ def repositories
51
+ return @cache if defined?(@cache)
52
+ # parse the repository data from yum
53
+ # we cannot use -C, because this is not reliable and may lead to errors
54
+ @command_result = inspec.command('yum -v repolist all')
55
+ @content = @command_result.stdout
56
+ @cache = []
57
+ repo = {}
58
+ in_repo = false
59
+ @content.each_line do |line|
60
+ # detect repo start
61
+ in_repo = true if line =~ /^\s*Repo-id\s*:\s*(.*)\b/
62
+ # detect repo end
63
+ if line == "\n" && in_repo
64
+ in_repo = false
65
+ @cache.push(repo)
66
+ repo = {}
67
+ end
68
+ # parse repo content
69
+ if in_repo == true
70
+ val = /^\s*([^:]*?)\s*:\s*(.*?)\s*$/.match(line)
71
+ repo[repo_key(strip(val[1]))] = strip(val[2])
72
+ end
71
73
  end
74
+ @cache
72
75
  end
73
- @cache
74
- end
75
76
 
76
- def repos
77
- repositories.map { |repo| repo['id'] }
78
- end
77
+ def repos
78
+ repositories.map { |repo| repo['id'] }
79
+ end
79
80
 
80
- def repo(repo)
81
- YumRepo.new(self, repo)
82
- end
81
+ def repo(repo)
82
+ YumRepo.new(self, repo)
83
+ end
83
84
 
84
- # alias for yum.repo('reponame')
85
- def method_missing(name)
86
- repo(name.to_s) if !name.nil?
87
- end
85
+ # alias for yum.repo('reponame')
86
+ def method_missing(name)
87
+ repo(name.to_s) if !name.nil?
88
+ end
88
89
 
89
- def to_s
90
- 'Yum Repository'
91
- end
90
+ def to_s
91
+ 'Yum Repository'
92
+ end
92
93
 
93
- private
94
+ private
94
95
 
95
- # Removes lefthand and righthand whitespace
96
- def strip(value)
97
- value.strip if !value.nil?
98
- end
96
+ # Removes lefthand and righthand whitespace
97
+ def strip(value)
98
+ value.strip if !value.nil?
99
+ end
99
100
 
100
- # Optimize the key value
101
- def repo_key(key)
102
- return key if key.nil?
103
- key.gsub('Repo-', '').downcase
101
+ # Optimize the key value
102
+ def repo_key(key)
103
+ return key if key.nil?
104
+ key.gsub('Repo-', '').downcase
105
+ end
104
106
  end
105
- end
106
107
 
107
- class YumRepo
108
- def initialize(yum, reponame)
109
- @yum = yum
110
- @reponame = reponame
111
- end
108
+ class YumRepo
109
+ def initialize(yum, reponame)
110
+ @yum = yum
111
+ @reponame = reponame
112
+ end
112
113
 
113
- # extracts the shortname from a repo id
114
- # e.g. extras/7/x86_64 -> extras
115
- def shortname(id)
116
- val = %r{^\s*([^/]*?)/(.*?)\s*$}.match(id)
117
- val.nil? ? nil : val[1]
118
- end
114
+ # extracts the shortname from a repo id
115
+ # e.g. extras/7/x86_64 -> extras
116
+ def shortname(id)
117
+ val = %r{^\s*([^/]*?)/(.*?)\s*$}.match(id)
118
+ val.nil? ? nil : val[1]
119
+ end
119
120
 
120
- def info
121
- return @cache if defined?(@cache)
122
- selection = @yum.repositories.select { |e| e['id'] == @reponame || shortname(e['id']) == @reponame }
123
- @cache = selection[0] if !selection.nil? && selection.length == 1
124
- @cache
125
- end
121
+ def info
122
+ return @cache if defined?(@cache)
123
+ selection = @yum.repositories.select { |e| e['id'] == @reponame || shortname(e['id']) == @reponame }
124
+ @cache = selection[0] if !selection.nil? && selection.length == 1
125
+ @cache
126
+ end
126
127
 
127
- def exist?
128
- !info.nil?
129
- end
128
+ def exist?
129
+ !info.nil?
130
+ end
130
131
 
131
- def enabled?
132
- repo = info
133
- return false if repo.nil?
134
- info['status'] == 'enabled'
132
+ def enabled?
133
+ repo = info
134
+ return false if repo.nil?
135
+ info['status'] == 'enabled'
136
+ end
135
137
  end
136
- end
137
138
 
138
- # for compatability with serverspec
139
- # this is deprecated syntax and will be removed in future versions
140
- class YumRepoLegacy < Yum
141
- name 'yumrepo'
139
+ # for compatability with serverspec
140
+ # this is deprecated syntax and will be removed in future versions
141
+ class YumRepoLegacy < Yum
142
+ name 'yumrepo'
142
143
 
143
- def initialize(name)
144
- super()
145
- @repository = repo(name)
146
- end
144
+ def initialize(name)
145
+ super()
146
+ @repository = repo(name)
147
+ end
147
148
 
148
- def exists?
149
- deprecated
150
- @repository.exist?
151
- end
149
+ def exists?
150
+ deprecated
151
+ @repository.exist?
152
+ end
152
153
 
153
- def enabled?
154
- deprecated
155
- @repository.enabled?
156
- end
154
+ def enabled?
155
+ deprecated
156
+ @repository.enabled?
157
+ end
157
158
 
158
- def deprecated
159
- warn '[DEPRECATION] `yumrepo(reponame)` is deprecated. Please use `yum.repo(reponame)` instead.'
159
+ def deprecated
160
+ warn '[DEPRECATION] `yumrepo(reponame)` is deprecated. Please use `yum.repo(reponame)` instead.'
161
+ end
160
162
  end
161
163
  end