inspec 0.34.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +323 -6
  3. data/Gemfile +10 -0
  4. data/README.md +1 -1
  5. data/Rakefile +4 -55
  6. data/docs/.gitignore +2 -0
  7. data/docs/README.md +40 -0
  8. data/docs/cli.md +342 -0
  9. data/docs/dsl_inspec.md +245 -0
  10. data/docs/dsl_resource.md +93 -0
  11. data/docs/inspec_and_friends.md +105 -0
  12. data/docs/matchers.md +136 -0
  13. data/docs/plugin_kitchen_inspec.html.md +55 -0
  14. data/docs/profiles.md +285 -0
  15. data/docs/resources/apache_conf.md.erb +75 -0
  16. data/docs/resources/apt.md.erb +84 -0
  17. data/docs/resources/audit_policy.md.erb +61 -0
  18. data/docs/resources/auditd_conf.md.erb +79 -0
  19. data/docs/resources/auditd_rules.md.erb +132 -0
  20. data/docs/resources/bash.md.erb +84 -0
  21. data/docs/resources/bond.md.erb +97 -0
  22. data/docs/resources/bridge.md.erb +67 -0
  23. data/docs/resources/bsd_service.md.erb +76 -0
  24. data/docs/resources/command.md.erb +151 -0
  25. data/docs/resources/csv.md.erb +62 -0
  26. data/docs/resources/directory.md.erb +43 -0
  27. data/docs/resources/etc_group.md.erb +116 -0
  28. data/docs/resources/etc_passwd.md.erb +155 -0
  29. data/docs/resources/etc_shadow.md.erb +149 -0
  30. data/docs/resources/file.md.erb +460 -0
  31. data/docs/resources/gem.md.erb +73 -0
  32. data/docs/resources/group.md.erb +74 -0
  33. data/docs/resources/grub_conf.md.erb +115 -0
  34. data/docs/resources/host.md.erb +85 -0
  35. data/docs/resources/iis_site.md.erb +142 -0
  36. data/docs/resources/inetd_conf.md.erb +99 -0
  37. data/docs/resources/ini.md.erb +69 -0
  38. data/docs/resources/interface.md.erb +66 -0
  39. data/docs/resources/iptables.md.erb +70 -0
  40. data/docs/resources/json.md.erb +76 -0
  41. data/docs/resources/kernel_module.md.erb +60 -0
  42. data/docs/resources/kernel_parameter.md.erb +72 -0
  43. data/docs/resources/launchd_service.md.erb +76 -0
  44. data/docs/resources/limits_conf.md.erb +80 -0
  45. data/docs/resources/login_def.md.erb +77 -0
  46. data/docs/resources/mount.md.erb +83 -0
  47. data/docs/resources/mysql_conf.md.erb +102 -0
  48. data/docs/resources/mysql_session.md.erb +63 -0
  49. data/docs/resources/npm.md.erb +75 -0
  50. data/docs/resources/ntp_conf.md.erb +76 -0
  51. data/docs/resources/oneget.md.erb +67 -0
  52. data/docs/resources/os.md.erb +154 -0
  53. data/docs/resources/os_env.md.erb +98 -0
  54. data/docs/resources/package.md.erb +115 -0
  55. data/docs/resources/parse_config.md.erb +122 -0
  56. data/docs/resources/parse_config_file.md.erb +143 -0
  57. data/docs/resources/pip.md.erb +74 -0
  58. data/docs/resources/port.md.erb +150 -0
  59. data/docs/resources/postgres_conf.md.erb +90 -0
  60. data/docs/resources/postgres_session.md.erb +75 -0
  61. data/docs/resources/powershell.md.erb +116 -0
  62. data/docs/resources/process.md.erb +73 -0
  63. data/docs/resources/registry_key.md.erb +149 -0
  64. data/docs/resources/runit_service.md.erb +76 -0
  65. data/docs/resources/security_policy.md.erb +61 -0
  66. data/docs/resources/service.md.erb +135 -0
  67. data/docs/resources/ssh_config.md.erb +94 -0
  68. data/docs/resources/sshd_config.md.erb +97 -0
  69. data/docs/resources/ssl.md.erb +133 -0
  70. data/docs/resources/sys_info.md.erb +55 -0
  71. data/docs/resources/systemd_service.md.erb +76 -0
  72. data/docs/resources/sysv_service.md.erb +76 -0
  73. data/docs/resources/upstart_service.md.erb +76 -0
  74. data/docs/resources/user.md.erb +154 -0
  75. data/docs/resources/users.md.erb +140 -0
  76. data/docs/resources/vbscript.md.erb +69 -0
  77. data/docs/resources/windows_feature.md.erb +61 -0
  78. data/docs/resources/wmi.md.erb +95 -0
  79. data/docs/resources/xinetd_conf.md.erb +170 -0
  80. data/docs/resources/yaml.md.erb +69 -0
  81. data/docs/resources/yum.md.erb +103 -0
  82. data/docs/ruby_usage.md +154 -0
  83. data/docs/shared/matcher_be.md.erb +1 -0
  84. data/docs/shared/matcher_cmp.md.erb +45 -0
  85. data/docs/shared/matcher_eq.md.erb +3 -0
  86. data/docs/shared/matcher_include.md.erb +1 -0
  87. data/docs/shared/matcher_match.md.erb +1 -0
  88. data/docs/shell.md +150 -0
  89. data/examples/meta-profile/inspec.yml +2 -4
  90. data/inspec.gemspec +1 -1
  91. data/lib/bundles/inspec-compliance/api.rb +28 -18
  92. data/lib/bundles/inspec-compliance/cli.rb +19 -27
  93. data/lib/bundles/inspec-compliance/target.rb +15 -2
  94. data/lib/fetchers/git.rb +4 -0
  95. data/lib/fetchers/local.rb +16 -1
  96. data/lib/fetchers/mock.rb +4 -0
  97. data/lib/fetchers/url.rb +46 -20
  98. data/lib/inspec/base_cli.rb +14 -0
  99. data/lib/inspec/cached_fetcher.rb +67 -0
  100. data/lib/inspec/cli.rb +22 -8
  101. data/lib/inspec/control_eval_context.rb +12 -2
  102. data/lib/inspec/dependencies/{vendor_index.rb → cache.rb} +5 -4
  103. data/lib/inspec/dependencies/dependency_set.rb +8 -14
  104. data/lib/inspec/dependencies/lockfile.rb +5 -13
  105. data/lib/inspec/dependencies/requirement.rb +31 -41
  106. data/lib/inspec/dependencies/resolver.rb +3 -3
  107. data/lib/inspec/dsl.rb +16 -4
  108. data/lib/inspec/errors.rb +1 -0
  109. data/lib/inspec/fetcher.rb +25 -1
  110. data/lib/inspec/objects/each_loop.rb +5 -2
  111. data/lib/inspec/objects/test.rb +8 -2
  112. data/lib/inspec/plugins/fetcher.rb +13 -12
  113. data/lib/inspec/plugins/resource.rb +3 -0
  114. data/lib/inspec/profile.rb +62 -26
  115. data/lib/inspec/profile_context.rb +44 -8
  116. data/lib/inspec/resource.rb +18 -3
  117. data/lib/inspec/rspec_json_formatter.rb +91 -40
  118. data/lib/inspec/rule.rb +45 -2
  119. data/lib/inspec/runner.rb +51 -39
  120. data/lib/inspec/shell.rb +5 -16
  121. data/lib/inspec/version.rb +1 -1
  122. data/lib/resources/apache_conf.rb +1 -1
  123. data/lib/resources/gem.rb +1 -0
  124. data/lib/resources/groups.rb +190 -0
  125. data/lib/resources/oneget.rb +1 -0
  126. data/lib/resources/os.rb +1 -1
  127. data/lib/resources/package.rb +3 -1
  128. data/lib/resources/parse_config.rb +18 -1
  129. data/lib/resources/pip.rb +1 -1
  130. data/lib/resources/security_policy.rb +54 -0
  131. data/lib/resources/ssl.rb +9 -11
  132. data/lib/resources/sys_info.rb +1 -1
  133. data/lib/resources/users.rb +81 -64
  134. metadata +91 -17
  135. data/docs/cli.rst +0 -442
  136. data/docs/dsl_inspec.rst +0 -259
  137. data/docs/dsl_resource.rst +0 -90
  138. data/docs/inspec_and_friends.rst +0 -85
  139. data/docs/matchers.rst +0 -137
  140. data/docs/profiles.rst +0 -169
  141. data/docs/readme.rst +0 -105
  142. data/docs/resources.rst +0 -4836
  143. data/docs/ruby_usage.rst +0 -145
  144. data/docs/shell.rst +0 -130
  145. data/docs/template.rst +0 -51
  146. data/lib/resources/group.rb +0 -137
@@ -6,7 +6,31 @@ require 'inspec/plugins'
6
6
  require 'utils/plugin_registry'
7
7
 
8
8
  module Inspec
9
- Fetcher = PluginRegistry.new
9
+ class FetcherRegistry < PluginRegistry
10
+ def resolve(target)
11
+ if fetcher_specified?(target)
12
+ super(target)
13
+ else
14
+ Inspec::Log.debug("Assuming default supermarket source for #{target}")
15
+ super(with_default_fetcher(target))
16
+ end
17
+ end
18
+
19
+ NON_FETCHER_KEYS = [:name, :version_constraint, :cwd, :backend, :cache, :sha256].freeze
20
+ def fetcher_specified?(target)
21
+ # Only set a default for Hash-based (i.e. from
22
+ # inspec.yml/inspec.lock) targets
23
+
24
+ return true if !target.respond_to?(:keys)
25
+ !(target.keys - NON_FETCHER_KEYS).empty?
26
+ end
27
+
28
+ def with_default_fetcher(target)
29
+ target.merge({ supermarket: target[:name] })
30
+ end
31
+ end
32
+
33
+ Fetcher = FetcherRegistry.new
10
34
 
11
35
  def self.fetcher(version)
12
36
  if version != 1
@@ -2,10 +2,11 @@
2
2
 
3
3
  module Inspec
4
4
  class EachLoop < List
5
- attr_reader :tests
5
+ attr_reader :tests, :variables
6
6
  def initialize
7
7
  super
8
8
  @tests = []
9
+ @variables = []
9
10
  end
10
11
 
11
12
  def add_test(t = nil)
@@ -24,9 +25,11 @@ module Inspec
24
25
  end
25
26
 
26
27
  def to_ruby
28
+ vars = variables.map(&:to_ruby).join("\n")
29
+ vars += "\n" unless vars.empty?
27
30
  obj = super
28
31
  all_tests = @tests.map(&:to_ruby).join("\n").gsub("\n", "\n ")
29
- format("%s.each do |entry|\n %s\nend", obj, all_tests)
32
+ format("%s%s.each do |entry|\n %s\nend", vars, obj, all_tests)
30
33
  end
31
34
  end
32
35
  end
@@ -66,8 +66,14 @@ module Inspec
66
66
  res, xtra = describe_chain
67
67
  itsy = xtra.nil? ? 'it' : 'its(' + xtra.to_s.inspect + ')'
68
68
  naughty = @negated ? '_not' : ''
69
- xpect = defined?(@expectation) ? expectation.inspect+' ' : ''
70
- format("%sdescribe %s do\n %s { should%s %s %s}\nend",
69
+ xpect = defined?(@expectation) ? expectation.inspect : ''
70
+ if matcher == 'match'
71
+ # without this, xpect values like / \/zones\// will not be parsed properly
72
+ xpect = "(#{xpect})"
73
+ elsif xpect != ''
74
+ xpect = ' ' + xpect
75
+ end
76
+ format("%sdescribe %s do\n %s { should%s %s%s }\nend",
71
77
  vars, res, itsy, naughty, matcher, xpect)
72
78
  end
73
79
 
@@ -24,6 +24,12 @@ module Inspec
24
24
  Inspec::Fetcher
25
25
  end
26
26
 
27
+ attr_accessor :target
28
+
29
+ def writable?
30
+ false
31
+ end
32
+
27
33
  #
28
34
  # The path to the archive on disk. This can be passed to a
29
35
  # FileProvider to get access to the files in the fetched
@@ -56,6 +62,13 @@ module Inspec
56
62
  fail "Fetcher #{self} does not implement `resolved_source()`. This is required for terminal fetchers."
57
63
  end
58
64
 
65
+ #
66
+ # The unique key based on the content of the remote archive.
67
+ #
68
+ def cache_key
69
+ fail "Fetcher #{self} does not implement `cache_key()`. This is required for terminal fetchers."
70
+ end
71
+
59
72
  #
60
73
  # relative_target is provided to keep compatibility with 3rd
61
74
  # party plugins.
@@ -69,18 +82,6 @@ module Inspec
69
82
  file_provider = Inspec::FileProvider.for_path(archive_path)
70
83
  file_provider.relative_provider
71
84
  end
72
-
73
- #
74
- # A string based on the components of the resolved source,
75
- # suitable for constructing per-source file names.
76
- #
77
- def cache_key
78
- key = ''
79
- resolved_source.each do |k, v|
80
- key << "#{k}:#{v}"
81
- end
82
- Digest::SHA256.hexdigest key
83
- end
84
85
  end
85
86
  end
86
87
  end
@@ -72,6 +72,9 @@ module Inspec
72
72
  end
73
73
 
74
74
  # rubocop:enable Lint/NestedMethodDefinition
75
+ if __resource_registry.key?(name)
76
+ Inspec::Log.warn("Overwriting resource #{name}. To reference a specific version of #{name} use the resource() method")
77
+ end
75
78
  __resource_registry[name] = cl
76
79
  end
77
80
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  require 'forwardable'
7
7
  require 'inspec/polyfill'
8
- require 'inspec/fetcher'
8
+ require 'inspec/cached_fetcher'
9
9
  require 'inspec/file_provider'
10
10
  require 'inspec/source_reader'
11
11
  require 'inspec/metadata'
@@ -13,7 +13,7 @@ require 'inspec/backend'
13
13
  require 'inspec/rule'
14
14
  require 'inspec/log'
15
15
  require 'inspec/profile_context'
16
- require 'inspec/dependencies/vendor_index'
16
+ require 'inspec/dependencies/cache'
17
17
  require 'inspec/dependencies/lockfile'
18
18
  require 'inspec/dependencies/dependency_set'
19
19
 
@@ -22,19 +22,7 @@ module Inspec
22
22
  extend Forwardable
23
23
 
24
24
  def self.resolve_target(target, cache = nil)
25
- cache ||= VendorIndex.new
26
- fetcher = Inspec::Fetcher.resolve(target)
27
- if fetcher.nil?
28
- fail("Could not fetch inspec profile in #{target.inspect}.")
29
- end
30
-
31
- if cache.exists?(fetcher.cache_key)
32
- Inspec::Log.debug "Using cached dependency for #{target}"
33
- cache.prefered_entry_for(fetcher.cache_key)
34
- else
35
- fetcher.fetch(cache.base_path_for(fetcher.cache_key))
36
- fetcher.archive_path
37
- end
25
+ Inspec::CachedFetcher.new(target, cache || Cache.new)
38
26
  end
39
27
 
40
28
  def self.for_path(path, opts)
@@ -47,12 +35,17 @@ module Inspec
47
35
  new(reader, opts)
48
36
  end
49
37
 
38
+ def self.for_fetcher(fetcher, opts)
39
+ path, writable = fetcher.fetch
40
+ for_path(path, opts.merge(target: fetcher.target, writable: writable))
41
+ end
42
+
50
43
  def self.for_target(target, opts = {})
51
- for_path(resolve_target(target, opts[:cache]), opts.merge(target: target))
44
+ fetcher = resolve_target(target, opts[:cache])
45
+ for_fetcher(fetcher, opts)
52
46
  end
53
47
 
54
- attr_reader :source_reader
55
- attr_accessor :runner_context
48
+ attr_reader :source_reader, :backend, :runner_context
56
49
  def_delegator :@source_reader, :tests
57
50
  def_delegator :@source_reader, :libraries
58
51
  def_delegator :@source_reader, :metadata
@@ -63,10 +56,13 @@ module Inspec
63
56
  @logger = options[:logger] || Logger.new(nil)
64
57
  @locked_dependencies = options[:dependencies]
65
58
  @controls = options[:controls] || []
59
+ @writable = options[:writable] || false
66
60
  @profile_id = options[:id]
61
+ @cache = options[:cache] || Cache.new
67
62
  @backend = options[:backend] || Inspec::Backend.create(options)
68
63
  @source_reader = source_reader
69
64
  @tests_collected = false
65
+ @libraries_loaded = false
70
66
  Metadata.finalize(@source_reader.metadata, @profile_id)
71
67
  @runner_context = options[:profile_context] || Inspec::ProfileContext.for_profile(self,
72
68
  @backend,
@@ -77,6 +73,32 @@ module Inspec
77
73
  metadata.params[:name]
78
74
  end
79
75
 
76
+ def version
77
+ metadata.params[:version]
78
+ end
79
+
80
+ def writable? # rubocop:disable Style/TrivialAccessors
81
+ @writable
82
+ end
83
+
84
+ #
85
+ # Is this profile is supported on the current platform of the
86
+ # backend machine and the current inspec version.
87
+ #
88
+ # @returns [TrueClass, FalseClass]
89
+ #
90
+ def supported?
91
+ supports_os? && supports_runtime?
92
+ end
93
+
94
+ def supports_os?
95
+ metadata.supports_transport?(@backend)
96
+ end
97
+
98
+ def supports_runtime?
99
+ metadata.supports_runtime?
100
+ end
101
+
80
102
  def params
81
103
  @params ||= load_params
82
104
  end
@@ -104,6 +126,8 @@ module Inspec
104
126
  end
105
127
 
106
128
  def load_libraries
129
+ return @runner_context if @libraries_loaded
130
+
107
131
  locked_dependencies.each do |d|
108
132
  c = d.load_libraries
109
133
  @runner_context.add_resources(c)
@@ -114,6 +138,7 @@ module Inspec
114
138
  end
115
139
 
116
140
  @runner_context.load_libraries(libs)
141
+ @libraries_loaded = true
117
142
  @runner_context
118
143
  end
119
144
 
@@ -121,19 +146,29 @@ module Inspec
121
146
  "Inspec::Profile<#{name}>"
122
147
  end
123
148
 
124
- def info
125
- res = params.dup
149
+ # return info using uncached params
150
+ def info!
151
+ info(load_params.dup)
152
+ end
153
+
154
+ def info(res = params.dup)
126
155
  # add information about the controls
127
- controls = res[:controls].map do |id, rule|
156
+ res[:controls] = res[:controls].map do |id, rule|
128
157
  next if id.to_s.empty?
129
158
  data = rule.dup
130
159
  data.delete(:checks)
131
160
  data[:impact] ||= 0.5
132
161
  data[:impact] = 1.0 if data[:impact] > 1.0
133
162
  data[:impact] = 0.0 if data[:impact] < 0.0
134
- [id, data]
163
+ data[:id] = id
164
+ data
165
+ end.compact
166
+
167
+ # resolve hash structure in groups
168
+ res[:groups] = res[:groups].map do |id, group|
169
+ group[:id] = id
170
+ group
135
171
  end
136
- res[:controls] = Hash[controls.compact]
137
172
 
138
173
  # add information about the required attributes
139
174
  res[:attributes] = res[:attributes].map(&:to_hash) unless res[:attributes].nil? || res[:attributes].empty?
@@ -308,14 +343,14 @@ module Inspec
308
343
  # @param vendor_path [String] Path to the on-disk vendor dir
309
344
  # @return [Inspec::Lockfile]
310
345
  #
311
- def generate_lockfile(vendor_path = nil)
312
- res = Inspec::DependencySet.new(cwd, vendor_path, nil, @backend)
346
+ def generate_lockfile
347
+ res = Inspec::DependencySet.new(cwd, @cache, nil, @backend)
313
348
  res.vendor(metadata.dependencies)
314
349
  Inspec::Lockfile.from_dependency_set(res)
315
350
  end
316
351
 
317
352
  def load_dependencies
318
- Inspec::DependencySet.from_lockfile(lockfile, cwd, nil, @backend)
353
+ Inspec::DependencySet.from_lockfile(lockfile, cwd, @cache, @backend)
319
354
  end
320
355
 
321
356
  private
@@ -353,6 +388,7 @@ module Inspec
353
388
  params[:groups] = groups = {}
354
389
  prefix = @source_reader.target.prefix || ''
355
390
  tests.each do |rule|
391
+ next if rule.nil?
356
392
  f = load_rule_filepath(prefix, rule)
357
393
  load_rule(rule, f, controls, groups)
358
394
  end
@@ -17,7 +17,8 @@ module Inspec
17
17
  'attributes' => attributes })
18
18
  end
19
19
 
20
- attr_reader :attributes, :rules, :profile_id, :resource_registry
20
+ attr_reader :attributes, :profile_id, :resource_registry, :backend
21
+ attr_accessor :rules
21
22
  def initialize(profile_id, backend, conf)
22
23
  if backend.nil?
23
24
  fail 'ProfileContext is initiated with a backend == nil. ' \
@@ -27,7 +28,8 @@ module Inspec
27
28
  @backend = backend
28
29
  @conf = conf.dup
29
30
  @rules = {}
30
- @subcontexts = []
31
+ @control_subcontexts = []
32
+ @lib_subcontexts = []
31
33
  @require_loader = ::Inspec::RequireLoader.new
32
34
  @attributes = []
33
35
  # A local resource registry that only contains resources defined
@@ -45,7 +47,7 @@ module Inspec
45
47
  end
46
48
 
47
49
  def to_resources_dsl
48
- Inspec::Resource.create_dsl(@backend, @resource_registry)
50
+ Inspec::Resource.create_dsl(self)
49
51
  end
50
52
 
51
53
  def control_eval_context
@@ -59,20 +61,47 @@ module Inspec
59
61
  @control_eval_context = nil
60
62
  end
61
63
 
62
- def all_rules
64
+ def profile_supports_os?
65
+ return true if @conf['profile'].nil?
66
+
67
+ @conf['profile'].supports_os?
68
+ end
69
+
70
+ def remove_rule(id)
71
+ @rules[id] = nil if @rules.key?(id)
72
+ @control_subcontexts.each do |c|
73
+ c.remove_rule(id)
74
+ end
75
+ end
76
+
77
+ def all_controls
63
78
  ret = @rules.values
64
- ret += @subcontexts.map(&:all_rules).flatten
79
+ ret += @control_subcontexts.map(&:all_rules).flatten
65
80
  ret
66
81
  end
82
+ alias all_rules all_controls
83
+
84
+ def subcontext_by_name(name)
85
+ found = @lib_subcontexts.find { |c| c.profile_id == name }
86
+ if !found
87
+ @lib_subcontexts.each do |c|
88
+ found = c.subcontext_by_name(name)
89
+ break if found
90
+ end
91
+ end
92
+
93
+ found
94
+ end
67
95
 
68
96
  def add_resources(context)
69
97
  @resource_registry.merge!(context.resource_registry)
70
98
  control_eval_context.add_resources(context)
99
+ @lib_subcontexts << context
71
100
  reload_dsl
72
101
  end
73
102
 
74
103
  def add_subcontext(context)
75
- @subcontexts << context
104
+ @control_subcontexts << context
76
105
  end
77
106
 
78
107
  def load_libraries(libs)
@@ -122,10 +151,17 @@ module Inspec
122
151
  @rules.delete(full_id(@profile_id, id))
123
152
  end
124
153
 
154
+ attr_reader :current_load
155
+
125
156
  def register_rule(r)
126
157
  # get the full ID
127
- r.instance_variable_set(:@__file, @current_load[:file])
128
- r.instance_variable_set(:@__group_title, @current_load[:title])
158
+ file = if @current_load.nil?
159
+ 'unknown'
160
+ else
161
+ @current_load[:file] || 'unknown'
162
+ end
163
+ r.instance_variable_set(:@__file, file)
164
+ r.instance_variable_set(:@__group_title, current_load[:title])
129
165
 
130
166
  # add the rule to the registry
131
167
  fid = full_id(Inspec::Rule.profile_id(r), Inspec::Rule.rule_id(r))
@@ -6,6 +6,8 @@
6
6
  require 'inspec/plugins'
7
7
 
8
8
  module Inspec
9
+ class ProfileNotFound < StandardError; end
10
+
9
11
  class Resource
10
12
  def self.default_registry
11
13
  @default_registry ||= {}
@@ -25,9 +27,22 @@ module Inspec
25
27
  #
26
28
  # @param backend [BackendRunner] exposing the target to resources
27
29
  # @return [ResourcesDSL]
28
- def self.create_dsl(backend, my_registry = registry)
29
- # need the local name, to use it in the module creation further down
30
+ def self.create_dsl(profile_context)
31
+ backend = profile_context.backend
32
+ my_registry = profile_context.resource_registry
33
+
30
34
  Module.new do
35
+ define_method :resource_class do |profile_name, resource_name|
36
+ inner_context = if profile_name == profile_context.profile_id
37
+ profile_context
38
+ else
39
+ profile_context.subcontext_by_name(profile_name)
40
+ end
41
+
42
+ fail ProfileNotFound, "Cannot find profile named: #{profile_name}" if inner_context.nil?
43
+ inner_context.resource_registry[resource_name]
44
+ end
45
+
31
46
  my_registry.each do |id, r|
32
47
  define_method id.to_sym do |*args|
33
48
  r.new(backend, id.to_s, *args)
@@ -68,7 +83,7 @@ require 'resources/directory'
68
83
  require 'resources/etc_group'
69
84
  require 'resources/file'
70
85
  require 'resources/gem'
71
- require 'resources/group'
86
+ require 'resources/groups'
72
87
  require 'resources/grub_conf'
73
88
  require 'resources/host'
74
89
  require 'resources/iis_site'