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,140 @@
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/provider'
21
+
22
+ module Garcon
23
+ module Resource
24
+ # Combine a resource and provider class for quick and easy oven baked
25
+ # goodness. Never has cooking been this fun since the invention of the
26
+ # grocery store!
27
+ #
28
+ # @example
29
+ # class Chef::Resource::HouseKeeping < Chef::Resource
30
+ # include Garcon(blender: true)
31
+ #
32
+ # attribute :path,
33
+ # kind_of: String,
34
+ # name_attribute: true
35
+ # attribute :message,
36
+ # kind_of: String,
37
+ # default: 'Clean the kitchen'
38
+ #
39
+ # action :run do
40
+ # file new_resource.path do
41
+ # content new_resource.message
42
+ # end
43
+ # end
44
+ # end
45
+ #
46
+ module Blender
47
+ # Coerce is_a? so that the DSL will consider this a Provider for the
48
+ # purposes of attaching enclosing_provider.
49
+ #
50
+ # @param klass [Class]
51
+ #
52
+ # @return [Boolean]
53
+ #
54
+ # @api private
55
+ def is_a?(klass)
56
+ klass == Chef::Provider ? true : super
57
+ end
58
+
59
+ # Coerce provider_for_action so that the resource is also the provider.
60
+ #
61
+ # @param action [Symbol]
62
+ #
63
+ # @return [Chef::Provider]
64
+ #
65
+ # @api private
66
+ def provider_for_action(action)
67
+ provider(self.class.blender_provider_class) unless provider
68
+ super
69
+ end
70
+
71
+ module ClassMethods
72
+ # Define a provider action. The block should contain the usual provider
73
+ # code.
74
+ #
75
+ # @param name [Symbol]
76
+ # Name of the action.
77
+ #
78
+ # @param block [Proc]
79
+ # Action implementation.
80
+ #
81
+ def action(name, &block)
82
+ blender_actions[name.to_sym] = block
83
+ actions(name.to_sym) if respond_to?(:actions)
84
+ end
85
+
86
+ # Storage accessor for blended action blocks. Maps action name to proc.
87
+ #
88
+ # @return [Hash<Symbol, Proc>]
89
+ #
90
+ # @api private
91
+ def blender_actions
92
+ (@blender_actions ||= {})
93
+ end
94
+
95
+ # Create a provider class for the blender actions in this resource.
96
+ # Inherits from the blender provider class of the resource's
97
+ # superclass if present.
98
+ #
99
+ # @return [Class]
100
+ #
101
+ # @api private
102
+ def blender_provider_class
103
+ @blender_provider_class ||= begin
104
+ provider_superclass = begin
105
+ self.superclass.blender_provider_class
106
+ rescue NoMethodError
107
+ Chef::Provider
108
+ end
109
+ actions = blender_actions
110
+ class_name = self.name
111
+ Class.new(provider_superclass) do
112
+ include Garcon
113
+ define_singleton_method(:name) { class_name + ' (blender)' }
114
+ actions.each do |action, block|
115
+ define_method(:"action_#{action}", &block)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ # Hook called when module is included, extends a descendant with class
122
+ # and instance methods.
123
+ #
124
+ # @param [Module] descendant
125
+ # The module or class including Garcon::Resource::Blender
126
+ #
127
+ # @return [self]
128
+ #
129
+ # @api private
130
+ def included(descendant)
131
+ super
132
+ descendant.extend ClassMethods
133
+ end
134
+ end
135
+
136
+ extend ClassMethods
137
+ end
138
+ end
139
+ end
140
+
@@ -0,0 +1,66 @@
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 Resource
22
+ # Resource mixin to allow lazyily-evaluated defaults in resource attributes.
23
+ #
24
+ module LazyEval
25
+ module ClassMethods
26
+ # Create a lazyily-evaluated block.
27
+ #
28
+ # @param [Proc] block
29
+ # Callable to return the default value.
30
+ #
31
+ # @return [Chef::DelayedEvaluator]
32
+ #
33
+ def lazy(&block)
34
+ Chef::DelayedEvaluator.new(&block)
35
+ end
36
+
37
+ # Hook called when module is included, extends a descendant with class
38
+ # and instance methods.
39
+ #
40
+ # @param [Module] descendant
41
+ # the module or class including Garcon::Resource::LazyEval
42
+ #
43
+ # @return [self]
44
+ #
45
+ def included(descendant)
46
+ super
47
+ descendant.extend ClassMethods
48
+ end
49
+ end
50
+
51
+ extend ClassMethods
52
+
53
+ # Override the default set_or_return to support lazy evaluation of the
54
+ # default value. This only actually matters when it is called from a class
55
+ # level context via #attributes.
56
+ #
57
+ def set_or_return(symbol, arg, validation)
58
+ if validation && validation[:default].is_a?(Chef::DelayedEvaluator)
59
+ validation = validation.dup
60
+ validation[:default] = instance_eval(&validation[:default])
61
+ end
62
+ super(symbol, arg, validation)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,109 @@
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 Resource
22
+ # Helper module to automatically set @resource_name.
23
+ #
24
+ # @example
25
+ # class MyResource < Chef::Resource
26
+ # include Garcon
27
+ #
28
+ # provides :my_resource
29
+ # end
30
+ #
31
+ module ResourceName
32
+ # Constructor for Chef::Resource::MyResource.
33
+ #
34
+ def initialize(*args)
35
+ super
36
+ if self.class.resource_name(false)
37
+ @resource_name = self.class.resource_name
38
+ else
39
+ @resource_name ||= self.class.resource_name
40
+ end
41
+ end
42
+
43
+ module ClassMethods
44
+ # Maps a resource/provider (and optionally a platform and version) to a
45
+ # Chef resource/provider. This allows finer grained per platform
46
+ # resource attributes and the end of overloaded resource definitions.
47
+ #
48
+ # @note
49
+ # The provides method must be defined in both the custom resource and
50
+ # custom provider files and both files must have identical provides
51
+ # statement(s).
52
+ #
53
+ # @param [Symbol] name
54
+ # Name of a Chef resource/provider to map to.
55
+ #
56
+ # @return [undefined]
57
+ #
58
+ def provides(name)
59
+ if self.name && respond_to?(:constantize)
60
+ old_constantize = instance_method(:constantize)
61
+ define_singleton_method(:constantize) do |name|
62
+ name == self.name ? self : old_constantize.bind(self).call(name)
63
+ end
64
+ end
65
+ @provides_name = name
66
+ super if defined?(super)
67
+ end
68
+
69
+ # Return the Snake case name of the current resource class. If not set
70
+ # explicitly it will be introspected based on the class name.
71
+ #
72
+ # @param [Boolean] auto
73
+ # Try to auto-detect based on class name.
74
+ #
75
+ # @return [Symbol]
76
+ #
77
+ def resource_name(auto = true)
78
+ return @provides_name if @provides_name
79
+ @provides_name || if name && name.start_with?('Chef::Resource')
80
+ Garcon::Inflections.snakeify(name, 'Chef::Resource').to_sym
81
+ elsif name
82
+ Garcon::Inflections.snakeify(name.split('::').last).to_sym
83
+ end
84
+ end
85
+
86
+ # Used by Resource#to_text to find the human name for the resource.
87
+ #
88
+ def dsl_name
89
+ resource_name.to_s
90
+ end
91
+
92
+ # Hook called when module is included, extends a descendant with class
93
+ # and instance methods.
94
+ #
95
+ # @param [Module] descendant
96
+ # the module or class including Garcon::Resource::ResourceName
97
+ #
98
+ # @return [self]
99
+ #
100
+ def included(descendant)
101
+ super
102
+ descendant.extend ClassMethods
103
+ end
104
+ end
105
+
106
+ extend ClassMethods
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,204 @@
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
+ # Library routine that returns an encrypted data bag value for a supplied
22
+ # string. The key used in decrypting the encrypted value should be located
23
+ # at node[:garcon][:secret][:key_path].
24
+ #
25
+ # Note that if node[:garcon][:devmode] is true, then the value of the index
26
+ # parameter is just returned as-is. This means that in developer mode, if a
27
+ # cookbook does this:
28
+ #
29
+ # @example
30
+ # class Chef
31
+ # class Recipe
32
+ # include Garcon::SecretBag
33
+ # end
34
+ # end
35
+ #
36
+ # admin = secret('bag_name', 'RoG+3xqKE23uc')
37
+ #
38
+ # That means admin will be 'RoG+3xqKE23uc'
39
+ #
40
+ # You also can provide a default password value in developer mode, like:
41
+ #
42
+ # node.set[:garcon][:secret][:passwd] = 'mysql_passwd'
43
+ # mysql_passwd = secret('passwords', 'eazypass')
44
+ #
45
+ # The mysql_passwd will == 'eazypass'
46
+ #
47
+ module SecretBag
48
+ include Garcon::Exceptions
49
+
50
+ def secret(bag_name, index)
51
+ if node[:garcon][:devmode]
52
+ dev_secret(index)
53
+ else
54
+ case node[:garcon][:databag_type]
55
+ when :encrypted
56
+ encrypted_secret(bag_name, index)
57
+ when :standard
58
+ standard_secret(bag_name, index)
59
+ when :vault
60
+ vault_secret('vault_' + bag_name, index)
61
+ else
62
+ raise InvalidDataBagType
63
+ end
64
+ end
65
+ end
66
+
67
+ def encrypted_secret(bag_name, index)
68
+ key_path = node[:garcon][:secret][:key_path]
69
+ Chef::Log.info "Loading encrypted databag #{bag_name}.#{index} " \
70
+ "using key at #{key_path}"
71
+ secret = Chef::EncryptedDataBagItem.load_secret key_path
72
+ Chef::EncryptedDataBagItem.load(bag_name, index, secret)[index]
73
+ end
74
+
75
+ def standard_secret(bag_name, index)
76
+ Chef::Log.info "Loading databag #{bag_name}.#{index}"
77
+ Chef::DataBagItem.load(bag_name, index)[index]
78
+ end
79
+
80
+ def vault_secret(bag_name, index)
81
+ begin
82
+ require 'chef-vault'
83
+ rescue LoadError
84
+ Chef::Log.warn "Missing gem 'chef-vault'"
85
+ end
86
+ Chef::Log.info "Loading vault secret #{index} from #{bag_name}"
87
+ ChefVault::Item.load(bag_name, index)[index]
88
+ end
89
+
90
+ # Return a password using either data bags or attributes for storage.
91
+ # The storage mechanism used is determined by the
92
+ # `node[:garcon][:use_databags]` attribute.
93
+ #
94
+ # @param [String] type
95
+ # password type, can be `:user`, `:service`, `:db` or `:token`
96
+ #
97
+ # @param [String] keys
98
+ # the identifier of the password
99
+ #
100
+ def get_password(type, key)
101
+ unless [:db, :user, :service, :token].include?(type)
102
+ Chef::Log.error "Unsupported type for get_password: #{type}"
103
+ return
104
+ end
105
+
106
+ if node[:garcon][:use_databags]
107
+ if type == :token
108
+ secret node[:garcon][:secret][:secrets_data_bag], key
109
+ else
110
+ secret node[:garcon][:secret]["#{type}_passwords_data_bag"], key
111
+ end
112
+ else
113
+ node[:garcon][:secret][key][type]
114
+ end
115
+ end
116
+
117
+ # Loads the encrypted data bag item and returns credentials for the
118
+ # environment or for a default key.
119
+ #
120
+ # @param [String] environment
121
+ # The environment
122
+ #
123
+ # @param [String] source
124
+ # The deployment source to load configuration for
125
+ #
126
+ # @return [Chef::DataBagItem]
127
+ # The data bag item
128
+ #
129
+ def data_bag_config_for(environment, source)
130
+ data_bag_item = encrypted_data_bag_for(environment, DATA_BAG)
131
+
132
+ if data_bag_item.has_key?(source)
133
+ data_bag_item[source]
134
+ elsif DATA_BAG == source
135
+ data_bag_item
136
+ else
137
+ {}
138
+ end
139
+ end
140
+
141
+ # Looks for the given data bag in the cache and if not found, will load a
142
+ # data bag item named for the chef_environment, or '_wildcard' value.
143
+ #
144
+ # @param [String] environment
145
+ # The environment.
146
+ #
147
+ # @param [String] data_bag
148
+ # The data bag to load.
149
+ #
150
+ # @return [Chef::Mash]
151
+ # The data bag item in Mash form.
152
+ #
153
+ def encrypted_data_bag_for(environment, data_bag)
154
+ @encrypted_data_bags = {} unless @encrypted_data_bags
155
+
156
+ if encrypted_data_bags[data_bag]
157
+ return get_from_data_bags_cache(data_bag)
158
+ else
159
+ data_bag_item = encrypted_data_bag_item(data_bag, environment)
160
+ data_bag_item ||= encrypted_data_bag_item(data_bag, WILDCARD)
161
+ data_bag_item ||= {}
162
+ @encrypted_data_bags[data_bag] = data_bag_item
163
+ return data_bag_item
164
+ end
165
+ end
166
+
167
+ # @return [Hash]
168
+ def encrypted_data_bags
169
+ @encrypted_data_bags
170
+ end
171
+
172
+ # Loads an entry from the encrypted_data_bags class variable.
173
+ #
174
+ # @param [String] dbag
175
+ # The data bag to find.
176
+ #
177
+ # @return [type] [description]
178
+ #
179
+ def get_from_data_bags_cache(data_bag)
180
+ encrypted_data_bags[data_bag]
181
+ end
182
+
183
+ # Loads an EncryptedDataBagItem from the Chef server and
184
+ # turns it into a Chef::Mash, giving it indifferent access. Returns
185
+ # nil when a data bag item is not found.
186
+ #
187
+ # @param [String] dbag
188
+ # @param [String] dbag_item
189
+ #
190
+ # @raise [Chef::Garcon::DataBagEncryptionError]
191
+ # When the data bag cannot be decrypted or transformed into a Mash for
192
+ # some reason.
193
+ #
194
+ # @return [Chef::Mash]
195
+ #
196
+ def encrypted_data_bag_item(dbag, dbag_item)
197
+ Mash.from_hash(Chef::EncryptedDataBagItem.load(dbag, dbag_item).to_hash)
198
+ rescue Net::HTTPServerException
199
+ nil
200
+ rescue NoMethodError
201
+ raise DataBagEncryptionError.new
202
+ end
203
+ end
204
+ end