garcun 0.0.2

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 (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