garcun 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +17 -0
  3. data/.gitignore +197 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE +201 -0
  7. data/README.md +521 -0
  8. data/Rakefile +47 -0
  9. data/garcun.gemspec +83 -0
  10. data/lib/garcon.rb +290 -0
  11. data/lib/garcon/chef/chef_helpers.rb +343 -0
  12. data/lib/garcon/chef/coerce/coercer.rb +134 -0
  13. data/lib/garcon/chef/coerce/coercions/boolean_definitions.rb +34 -0
  14. data/lib/garcon/chef/coerce/coercions/date_definitions.rb +32 -0
  15. data/lib/garcon/chef/coerce/coercions/date_time_definitions.rb +32 -0
  16. data/lib/garcon/chef/coerce/coercions/fixnum_definitions.rb +34 -0
  17. data/lib/garcon/chef/coerce/coercions/float_definitions.rb +32 -0
  18. data/lib/garcon/chef/coerce/coercions/hash_definitions.rb +29 -0
  19. data/lib/garcon/chef/coerce/coercions/integer_definitions.rb +31 -0
  20. data/lib/garcon/chef/coerce/coercions/string_definitions.rb +45 -0
  21. data/lib/garcon/chef/coerce/coercions/time_definitions.rb +32 -0
  22. data/lib/garcon/chef/handler/devreporter.rb +127 -0
  23. data/lib/garcon/chef/log.rb +64 -0
  24. data/lib/garcon/chef/node.rb +100 -0
  25. data/lib/garcon/chef/provider/civilize.rb +209 -0
  26. data/lib/garcon/chef/provider/development.rb +159 -0
  27. data/lib/garcon/chef/provider/download.rb +420 -0
  28. data/lib/garcon/chef/provider/house_keeping.rb +265 -0
  29. data/lib/garcon/chef/provider/node_cache.rb +31 -0
  30. data/lib/garcon/chef/provider/partial.rb +183 -0
  31. data/lib/garcon/chef/provider/recovery.rb +80 -0
  32. data/lib/garcon/chef/provider/zip_file.rb +271 -0
  33. data/lib/garcon/chef/resource/attribute.rb +52 -0
  34. data/lib/garcon/chef/resource/base_dsl.rb +174 -0
  35. data/lib/garcon/chef/resource/blender.rb +140 -0
  36. data/lib/garcon/chef/resource/lazy_eval.rb +66 -0
  37. data/lib/garcon/chef/resource/resource_name.rb +109 -0
  38. data/lib/garcon/chef/secret_bag.rb +204 -0
  39. data/lib/garcon/chef/validations.rb +76 -0
  40. data/lib/garcon/chef_inclusions.rb +151 -0
  41. data/lib/garcon/configuration.rb +138 -0
  42. data/lib/garcon/core_ext.rb +39 -0
  43. data/lib/garcon/core_ext/array.rb +27 -0
  44. data/lib/garcon/core_ext/binding.rb +64 -0
  45. data/lib/garcon/core_ext/boolean.rb +66 -0
  46. data/lib/garcon/core_ext/duration.rb +271 -0
  47. data/lib/garcon/core_ext/enumerable.rb +34 -0
  48. data/lib/garcon/core_ext/file.rb +127 -0
  49. data/lib/garcon/core_ext/filetest.rb +62 -0
  50. data/lib/garcon/core_ext/hash.rb +279 -0
  51. data/lib/garcon/core_ext/kernel.rb +159 -0
  52. data/lib/garcon/core_ext/lazy.rb +222 -0
  53. data/lib/garcon/core_ext/method_access.rb +243 -0
  54. data/lib/garcon/core_ext/module.rb +92 -0
  55. data/lib/garcon/core_ext/nil.rb +53 -0
  56. data/lib/garcon/core_ext/numeric.rb +44 -0
  57. data/lib/garcon/core_ext/object.rb +342 -0
  58. data/lib/garcon/core_ext/pathname.rb +152 -0
  59. data/lib/garcon/core_ext/process.rb +41 -0
  60. data/lib/garcon/core_ext/random.rb +497 -0
  61. data/lib/garcon/core_ext/string.rb +312 -0
  62. data/lib/garcon/core_ext/struct.rb +49 -0
  63. data/lib/garcon/core_ext/symbol.rb +170 -0
  64. data/lib/garcon/core_ext/time.rb +234 -0
  65. data/lib/garcon/exceptions.rb +101 -0
  66. data/lib/garcon/inflections.rb +237 -0
  67. data/lib/garcon/inflections/defaults.rb +79 -0
  68. data/lib/garcon/inflections/inflections.rb +182 -0
  69. data/lib/garcon/inflections/rules_collection.rb +37 -0
  70. data/lib/garcon/secret.rb +271 -0
  71. data/lib/garcon/stash/format.rb +114 -0
  72. data/lib/garcon/stash/journal.rb +226 -0
  73. data/lib/garcon/stash/queue.rb +83 -0
  74. data/lib/garcon/stash/serializer.rb +86 -0
  75. data/lib/garcon/stash/store.rb +435 -0
  76. data/lib/garcon/task.rb +31 -0
  77. data/lib/garcon/task/atomic.rb +151 -0
  78. data/lib/garcon/task/atomic_boolean.rb +127 -0
  79. data/lib/garcon/task/condition.rb +99 -0
  80. data/lib/garcon/task/copy_on_notify_observer_set.rb +154 -0
  81. data/lib/garcon/task/copy_on_write_observer_set.rb +153 -0
  82. data/lib/garcon/task/count_down_latch.rb +92 -0
  83. data/lib/garcon/task/delay.rb +196 -0
  84. data/lib/garcon/task/dereferenceable.rb +144 -0
  85. data/lib/garcon/task/event.rb +119 -0
  86. data/lib/garcon/task/executor.rb +275 -0
  87. data/lib/garcon/task/executor_options.rb +59 -0
  88. data/lib/garcon/task/future.rb +107 -0
  89. data/lib/garcon/task/immediate_executor.rb +84 -0
  90. data/lib/garcon/task/ivar.rb +171 -0
  91. data/lib/garcon/task/lazy_reference.rb +74 -0
  92. data/lib/garcon/task/monotonic_time.rb +69 -0
  93. data/lib/garcon/task/obligation.rb +256 -0
  94. data/lib/garcon/task/observable.rb +101 -0
  95. data/lib/garcon/task/priority_queue.rb +234 -0
  96. data/lib/garcon/task/processor_count.rb +128 -0
  97. data/lib/garcon/task/read_write_lock.rb +304 -0
  98. data/lib/garcon/task/safe_task_executor.rb +58 -0
  99. data/lib/garcon/task/single_thread_executor.rb +97 -0
  100. data/lib/garcon/task/thread_pool/cached.rb +71 -0
  101. data/lib/garcon/task/thread_pool/executor.rb +294 -0
  102. data/lib/garcon/task/thread_pool/fixed.rb +61 -0
  103. data/lib/garcon/task/thread_pool/worker.rb +90 -0
  104. data/lib/garcon/task/timer.rb +44 -0
  105. data/lib/garcon/task/timer_set.rb +194 -0
  106. data/lib/garcon/task/timer_task.rb +377 -0
  107. data/lib/garcon/task/waitable_list.rb +58 -0
  108. data/lib/garcon/utility/ansi.rb +199 -0
  109. data/lib/garcon/utility/at_random.rb +77 -0
  110. data/lib/garcon/utility/crypto.rb +292 -0
  111. data/lib/garcon/utility/equalizer.rb +146 -0
  112. data/lib/garcon/utility/faker/extensions/array.rb +22 -0
  113. data/lib/garcon/utility/faker/extensions/symbol.rb +9 -0
  114. data/lib/garcon/utility/faker/faker.rb +164 -0
  115. data/lib/garcon/utility/faker/faker/company.rb +17 -0
  116. data/lib/garcon/utility/faker/faker/hacker.rb +30 -0
  117. data/lib/garcon/utility/faker/faker/version.rb +3 -0
  118. data/lib/garcon/utility/faker/locales/en-US.yml +83 -0
  119. data/lib/garcon/utility/faker/locales/en.yml +21 -0
  120. data/lib/garcon/utility/file_helper.rb +170 -0
  121. data/lib/garcon/utility/hookers.rb +178 -0
  122. data/lib/garcon/utility/interpolation.rb +90 -0
  123. data/lib/garcon/utility/memstash.rb +364 -0
  124. data/lib/garcon/utility/misc.rb +54 -0
  125. data/lib/garcon/utility/msg_from_god.rb +62 -0
  126. data/lib/garcon/utility/retry.rb +238 -0
  127. data/lib/garcon/utility/timeout.rb +58 -0
  128. data/lib/garcon/utility/uber/builder.rb +91 -0
  129. data/lib/garcon/utility/uber/callable.rb +7 -0
  130. data/lib/garcon/utility/uber/delegates.rb +13 -0
  131. data/lib/garcon/utility/uber/inheritable_attr.rb +37 -0
  132. data/lib/garcon/utility/uber/options.rb +101 -0
  133. data/lib/garcon/utility/uber/uber_version.rb +3 -0
  134. data/lib/garcon/utility/uber/version.rb +33 -0
  135. data/lib/garcon/utility/url_helper.rb +100 -0
  136. data/lib/garcon/utils.rb +29 -0
  137. data/lib/garcon/version.rb +62 -0
  138. data/lib/garcun.rb +24 -0
  139. metadata +680 -0
@@ -0,0 +1,80 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Garcon
21
+ module Recovery
22
+ def run_action_rescued(action = nil)
23
+ run_action_unrescued(action)
24
+ Chef::Log.debug "Finished running #{new_resource.resource_name}" \
25
+ "[#{new_resource.name}] -- no exception"
26
+ rescue Exception => e
27
+ Chef::Log.info "#{new_resource.resource_name}[#{new_resource.name}] " \
28
+ "failed with: #{e.inspect}"
29
+
30
+ if new_resource.instance_variable_defined?('@recovery_handlers'.to_sym)
31
+ new_resource.recovery_handlers.each do |recovery_struct|
32
+ if recovery_struct.options[:retries] > 0 &&
33
+ (recovery_struct.exceptions.any? { |klass| e.is_a?(klass) } ||
34
+ recovery_struct.exceptions.empty?)
35
+
36
+ recovery_struct.options[:retries] -= 1
37
+ instance_exec(new_resource, &recovery_struct.block)
38
+ run_action_rescued(action)
39
+ return
40
+ end
41
+ end
42
+ end
43
+ raise exception
44
+ end
45
+
46
+ def notify(action, resource)
47
+ run_context.resource_collection.find(resource).run_action(action)
48
+ end
49
+
50
+ def self.included(descendant)
51
+ descendant.class_eval do
52
+ alias_method :run_action_unrescued, :run_action
53
+ alias_method :run_action, :run_action_rescued
54
+ end
55
+ end
56
+
57
+ unless Chef::Provider.ancestors.include?(Recovery)
58
+ Chef::Provider.send(:include, Recovery)
59
+ end
60
+ end
61
+ end
62
+
63
+ class Chef
64
+ class Resource
65
+ class Recovery < Struct.new(:options, :exceptions, :block); end
66
+
67
+ attr_accessor :recovery_handlers
68
+
69
+ def recovery(*args, &block)
70
+ options = { retries: 1 }
71
+ exceptions = []
72
+ args.each do |arg|
73
+ exceptions << arg if arg.is_a?(Class)
74
+ options.merge!(arg) if arg.is_a?(Hash)
75
+ end
76
+ @recovery_handlers ||= []
77
+ @recovery_handlers << Recovery.new(options || {}, exceptions || [], block)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,271 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'garcon'
21
+ require 'find'
22
+
23
+ class Chef
24
+ class Resource
25
+ class ZipFile < Chef::Resource
26
+ include Garcon
27
+
28
+ # Chef attributes
29
+ identity_attr :path
30
+ provides :zip_file
31
+ state_attrs :checksum, :owner, :group, :mode
32
+
33
+ # Actions
34
+ actions :zip, :unzip
35
+ default_action :unzip
36
+
37
+ # Attributes
38
+ attribute :path,
39
+ kind_of: String,
40
+ name_attribute: true
41
+ attribute :source,
42
+ kind_of: [String, URI::HTTP],
43
+ callbacks: source_callbacks,
44
+ required: true
45
+ attribute :remove_after,
46
+ kind_of: [TrueClass, FalseClass],
47
+ default: false
48
+ attribute :overwrite,
49
+ kind_of: [TrueClass, FalseClass],
50
+ default: false
51
+ attribute :checksum,
52
+ kind_of: String,
53
+ regex: /^[0-9a-f]{32}$|^[a-zA-Z0-9]{40,64}$/
54
+ attribute :owner,
55
+ kind_of: [String, Integer],
56
+ regex: Chef::Config[:user_valid_regex]
57
+ attribute :group,
58
+ kind_of: [String, Integer],
59
+ regex: Chef::Config[:group_valid_regex]
60
+ attribute :mode,
61
+ kind_of: Integer,
62
+ regex: /^0?\d{3,4}$/
63
+ attribute :check_cert,
64
+ kind_of: [TrueClass, FalseClass],
65
+ default: true
66
+ attribute :header,
67
+ kind_of: String
68
+ end
69
+ end
70
+
71
+ class Provider
72
+ class ZipFile < Chef::Provider
73
+ include Chef::Mixin::EnforceOwnershipAndPermissions
74
+ include Garcon
75
+
76
+ def initialize(new_resource, run_context)
77
+ super
78
+ require_zip unless defined?(Zip)
79
+ end
80
+
81
+ # Shortcut to new_resource.
82
+ #
83
+ alias_method :r, :new_resource
84
+
85
+ # Boolean indicating if WhyRun is supported by this provider.
86
+ #
87
+ # @return [TrueClass, FalseClass]
88
+ #
89
+ # @api private
90
+ def whyrun_supported?
91
+ true
92
+ end
93
+
94
+ # Load and return the current resource.
95
+ #
96
+ # @return [Chef::Provider::ZipFile]
97
+ #
98
+ # @api private
99
+ def load_current_resource
100
+ @current_resource ||= Chef::Resource::ZipFile.new(r.name)
101
+ @current_resource
102
+ end
103
+
104
+ def action_unzip
105
+ converge_by "Unzip #{r.source} to #{r.path}" do
106
+ Zip::File.open(cached_file) do |zip|
107
+ zip.each do |entry|
108
+ path = ::File.join(r.path, entry.name)
109
+ FileUtils.mkdir_p(::File.dirname(path))
110
+ if r.overwrite && ::File.exist?(path) && !::File.directory?(path)
111
+ FileUtils.rm(path)
112
+ end
113
+ zip.extract(entry, path)
114
+ end
115
+ end
116
+ do_acl_changes
117
+ ::File.unlink(cached_file) if r.remove_after
118
+ r.updated_by_last_action(true)
119
+ end
120
+ end
121
+
122
+ def action_zip
123
+ if ::File.exists?(r.path) && !r.overwrite
124
+ Chef::Log.info "#{r.path} already exists - nothing to do"
125
+ else
126
+ ::File.unlink(r.path) if ::File.exists?(r.path)
127
+ if ::File.directory?(r.source)
128
+ converge_by "Zip #{r.source}" do
129
+ z = Zip::File.new(r.path, true)
130
+ Find.find(r.source) do |f|
131
+ next if f == r.source
132
+ zip_fname = f.sub(r.source, '')
133
+ z.add(zip_fname, f)
134
+ end
135
+ z.close
136
+ do_acl_changes
137
+ r.updated_by_last_action(true)
138
+ end
139
+ else
140
+ Chef::Log.info 'a valid directory must be specified for ziping'
141
+ end
142
+ end
143
+ end
144
+
145
+ # Implementation components *should* follow symlinks when managing access
146
+ # control (e.g., use chmod instead of lchmod even if the path we're
147
+ # managing is a symlink).
148
+ #
149
+ def manage_symlink_access?
150
+ false
151
+ end
152
+
153
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
154
+
155
+ # Change file ownership and mode
156
+ #
157
+ # @return [undefined]
158
+ #
159
+ # @api private
160
+ def do_acl_changes
161
+ if access_controls.requires_changes?
162
+ converge_by(access_controls.describe_changes) do
163
+ access_controls.set_all
164
+ end
165
+ end
166
+ end
167
+
168
+ # Ensure all prerequisite software is installed.
169
+ #
170
+ # @return [undefined]
171
+ #
172
+ # @api private
173
+ def require_zip
174
+ require 'zip'
175
+ rescue LoadError
176
+ gem_rubyzip
177
+ require 'zip'
178
+ end
179
+
180
+ def gem_rubyzip
181
+ g ||= Chef::Resource::ChefGem.new('rubyzip', run_context)
182
+ g.compile_time(false) if respond_to?(:compile_time)
183
+ g.run_action :install
184
+ end
185
+
186
+ # Cache a file locally in Chef::Config[:file_cache_path].
187
+ #
188
+ # @note The file is gargbage collected at the end of a run.
189
+ #
190
+ # @return [String]
191
+ # Path to the cached file.
192
+ #
193
+ def cached_file
194
+ if r.source =~ URI::ABS_URI &&
195
+ %w[ftp http https].include?(URI.parse(r.source).scheme)
196
+ file = ::File.basename(URI.unescape(URI.parse(r.source).path))
197
+ cache_file_path = file_cache_path(file)
198
+
199
+ d ||= Chef::Resource::Download.new(cache_file_path, run_context)
200
+ d.backup false
201
+ d.source r.source
202
+ d.owner r.owner if r.owner
203
+ d.group r.group if r.group
204
+ d.header r.header if r.header
205
+ d.checksum r.checksum if r.checksum
206
+ d.check_cert r.check_cert
207
+ d.run_action :create
208
+ else
209
+ cache_file_path = r.source
210
+ end
211
+
212
+ cache_file_path
213
+ end
214
+ end
215
+ end
216
+ end
217
+
218
+ # Chef::Platform mapping for resource and providers
219
+ #
220
+ # @return [undefined]
221
+ #
222
+ # @api private.
223
+ Chef::Platform.set(
224
+ platform: :amazon,
225
+ resource: :zip_file,
226
+ provider: Chef::Provider::ZipFile
227
+ )
228
+
229
+ # Chef::Platform mapping for resource and providers
230
+ #
231
+ # @return [undefined]
232
+ #
233
+ # @api private.
234
+ Chef::Platform.set(
235
+ platform: :centos,
236
+ resource: :zip_file,
237
+ provider: Chef::Provider::ZipFile
238
+ )
239
+
240
+ # Chef::Platform mapping for resource and providers
241
+ #
242
+ # @return [undefined]
243
+ #
244
+ # @api private.
245
+ Chef::Platform.set(
246
+ platform: :oracle,
247
+ resource: :zip_file,
248
+ provider: Chef::Provider::ZipFile
249
+ )
250
+
251
+ # Chef::Platform mapping for resource and providers
252
+ #
253
+ # @return [undefined]
254
+ #
255
+ # @api private.
256
+ Chef::Platform.set(
257
+ platform: :redhat,
258
+ resource: :zip_file,
259
+ provider: Chef::Provider::ZipFile
260
+ )
261
+
262
+ # Chef::Platform mapping for resource and providers
263
+ #
264
+ # @return [undefined]
265
+ #
266
+ # @api private.
267
+ Chef::Platform.set(
268
+ platform: :scientific,
269
+ resource: :zip_file,
270
+ provider: Chef::Provider::ZipFile
271
+ )
@@ -0,0 +1,52 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/mash'
21
+ require 'chef/mixin/params_validate'
22
+
23
+ module Garcon
24
+ module Resource
25
+ class Attribute < ::Mash
26
+ include ::Chef::Mixin::ParamsValidate
27
+
28
+ def method_missing(method, *args, &block)
29
+ if (match = method.to_s.match(/(.*)=$/)) && args.size == 1
30
+ self[match[1]] = args.first
31
+ elsif (match = method.to_s.match(/(.*)\?$/)) && args.size == 0
32
+ key?(match[1])
33
+ elsif key?(method)
34
+ self[method]
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def validate(map)
41
+ data = super(symbolize_keys, map)
42
+ data.each { |k,v| self[k.to_sym] = v }
43
+ end
44
+
45
+ def self.from_hash(hash)
46
+ mash = Attribute.new(hash)
47
+ mash.default = hash.default
48
+ mash
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,174 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require_relative 'attribute'
21
+
22
+ module Garcon
23
+ module Resource
24
+ # Provide default_action and actions like LWRPBase.
25
+ #
26
+ module BaseDSL
27
+ module ClassMethods
28
+ # Imitate the behavior of the `Chef::Resource::LWRPBase` DSL providing
29
+ # a `default_action` method.
30
+ #
31
+ # @param [Symbol, String] name
32
+ # The default action.
33
+ #
34
+ # @return [undefined]
35
+ #
36
+ def default_action(name = nil)
37
+ if name
38
+ @default_action = name
39
+ actions(name)
40
+ end
41
+ @default_action || (superclass.respond_to?(:default_action) &&
42
+ superclass.default_action) ||
43
+ :actions.first || :nothing
44
+ end
45
+
46
+ # Imitate the behavior of the `Chef::Resource::LWRPBase` LWRP DSL
47
+ # providing a `action` method.
48
+ #
49
+ # @param [Array<String, Symbol>] name
50
+ # The default action.
51
+ #
52
+ # @return [undefined]
53
+ #
54
+ def actions(*names)
55
+ @actions ||= superclass.respond_to?(:actions) ?
56
+ superclass.actions.dup : []
57
+ (@actions << names).flatten!.uniq!
58
+ @actions
59
+ end
60
+
61
+ def basic(source = nil)
62
+ source ||= self
63
+ hash = Hash.new
64
+ pattern = Regexp.new('^_set_or_return_(.+)$')
65
+ source.public_methods(false).each do |method|
66
+ pattern.match(method) do |m|
67
+ attribute = m[1].to_sym
68
+ hash[attribute] = send(attribute)
69
+ end
70
+ end
71
+ Attribute.from_hash(hash)
72
+ end
73
+
74
+ def full(attribute = nil, source = nil, recursion = 3)
75
+ source ||= self
76
+ if attribute && (attribute.is_a?(Hash) || attribute.is_a?(Mash))
77
+ data = attribute
78
+ else
79
+ data = Hash.new
80
+ end
81
+ data = Mash.from_hash(data) unless data.is_a?(Mash)
82
+ data.merge!(attr_mash(source))
83
+ data = data.symbolize_keys
84
+ data.each do |k,v|
85
+ next unless v.is_a? String
86
+
87
+ for i in 1..recursion
88
+ v2 = v % data
89
+ v2 == v ? break : data[k] = v = v2
90
+ end
91
+ end
92
+ Attribute.from_hash(data)
93
+ end
94
+
95
+ # Imitate the behavior of the `Chef::Resource::LWRPBase` LWRP DSL
96
+ # providing a `attribute` method.
97
+ #
98
+ # @param [Symbol] name
99
+ #
100
+ # @param [Hash] opts
101
+ #
102
+ # @return [undefined]
103
+ #
104
+ def attribute(name, opts)
105
+ coerce = opts.delete(:coerce)
106
+ define_method(name) do |arg = nil, &block|
107
+ if coerce && !arg.nil?
108
+ arg = Garcon.coercer.coerce(arg, &coerce)
109
+ # arg = instance_exec(arg, &coerce)
110
+ else
111
+ arg = block if arg.nil?
112
+ end
113
+ set_or_return(name, arg, opts)
114
+ end
115
+ end
116
+
117
+ # Hook called when module is included, extends a descendant with class
118
+ # and instance methods.
119
+ #
120
+ # @param [Module] descendant
121
+ # the module or class including Garcon::Resource::BaseDSL
122
+ #
123
+ # @return [self]
124
+ #
125
+ def included(descendant)
126
+ super
127
+ descendant.extend ClassMethods
128
+ end
129
+ end
130
+
131
+ extend ClassMethods
132
+
133
+ # Constructor for Chef::Resource::YourSuperAwesomeResource.
134
+ #
135
+ def initialize(*args)
136
+ super
137
+ @action = self.class.default_action if @action == :nothing
138
+ (@allowed_actions << self.class.actions).flatten!.uniq!
139
+ end
140
+ end
141
+ end
142
+
143
+ module Provider
144
+ # Helper to handle load_current_resource for direct subclasses of Provider
145
+ #
146
+ module BaseDSL
147
+ module ClassMethods
148
+ # Hook called when module is included, extends a descendant with class
149
+ # and instance methods.
150
+ #
151
+ # @param [Module] descendant
152
+ # The module or class including Garcon::Provider::BaseDSL
153
+ #
154
+ # @return [self]
155
+ #
156
+ def included(descendant)
157
+ super
158
+ descendant.extend ClassMethods
159
+ if descendant.is_a?(Class) && descendant.superclass == Chef::Provider
160
+ descendant.class_exec { include Implementation }
161
+ end
162
+ descendant.class_exec { include Chef::DSL::Recipe }
163
+ end
164
+ end
165
+
166
+ module Implementation
167
+ def load_current_resource
168
+ end
169
+ end
170
+
171
+ extend ClassMethods
172
+ end
173
+ end
174
+ end