microwave 0.1004.1

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 (206) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +102 -0
  3. data/bin/chef-solo +25 -0
  4. data/lib/chef.rb +41 -0
  5. data/lib/chef/application.rb +147 -0
  6. data/lib/chef/application/solo.rb +181 -0
  7. data/lib/chef/applications.rb +1 -0
  8. data/lib/chef/checksum.rb +83 -0
  9. data/lib/chef/checksum_cache.rb +189 -0
  10. data/lib/chef/client.rb +325 -0
  11. data/lib/chef/config.rb +152 -0
  12. data/lib/chef/cookbook/chefignore.rb +66 -0
  13. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  14. data/lib/chef/cookbook/cookbook_version_loader.rb +173 -0
  15. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  16. data/lib/chef/cookbook/file_vendor.rb +48 -0
  17. data/lib/chef/cookbook/metadata.rb +629 -0
  18. data/lib/chef/cookbook/syntax_check.rb +136 -0
  19. data/lib/chef/cookbook_loader.rb +121 -0
  20. data/lib/chef/cookbook_version.rb +786 -0
  21. data/lib/chef/cookbook_version_selector.rb +151 -0
  22. data/lib/chef/environment.rb +267 -0
  23. data/lib/chef/exceptions.rb +150 -0
  24. data/lib/chef/file_access_control.rb +144 -0
  25. data/lib/chef/file_cache.rb +218 -0
  26. data/lib/chef/handler.rb +206 -0
  27. data/lib/chef/handler/error_report.rb +33 -0
  28. data/lib/chef/handler/json_file.rb +58 -0
  29. data/lib/chef/json_compat.rb +52 -0
  30. data/lib/chef/log.rb +39 -0
  31. data/lib/chef/mash.rb +211 -0
  32. data/lib/chef/mixin/check_helper.rb +31 -0
  33. data/lib/chef/mixin/checksum.rb +32 -0
  34. data/lib/chef/mixin/command.rb +221 -0
  35. data/lib/chef/mixin/command/unix.rb +215 -0
  36. data/lib/chef/mixin/command/windows.rb +76 -0
  37. data/lib/chef/mixin/convert_to_class_name.rb +63 -0
  38. data/lib/chef/mixin/create_path.rb +57 -0
  39. data/lib/chef/mixin/deep_merge.rb +225 -0
  40. data/lib/chef/mixin/deprecation.rb +65 -0
  41. data/lib/chef/mixin/from_file.rb +50 -0
  42. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  43. data/lib/chef/mixin/language.rb +125 -0
  44. data/lib/chef/mixin/language_include_attribute.rb +61 -0
  45. data/lib/chef/mixin/language_include_recipe.rb +52 -0
  46. data/lib/chef/mixin/params_validate.rb +225 -0
  47. data/lib/chef/mixin/recipe_definition_dsl_core.rb +78 -0
  48. data/lib/chef/mixin/shell_out.rb +41 -0
  49. data/lib/chef/mixin/template.rb +95 -0
  50. data/lib/chef/mixin/xml_escape.rb +140 -0
  51. data/lib/chef/mixins.rb +15 -0
  52. data/lib/chef/monkey_patches/dir.rb +36 -0
  53. data/lib/chef/monkey_patches/numeric.rb +15 -0
  54. data/lib/chef/monkey_patches/object.rb +9 -0
  55. data/lib/chef/monkey_patches/regexp.rb +34 -0
  56. data/lib/chef/monkey_patches/string.rb +49 -0
  57. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  58. data/lib/chef/nil_argument.rb +3 -0
  59. data/lib/chef/node.rb +469 -0
  60. data/lib/chef/node/attribute.rb +487 -0
  61. data/lib/chef/platform.rb +409 -0
  62. data/lib/chef/provider.rb +124 -0
  63. data/lib/chef/provider/breakpoint.rb +31 -0
  64. data/lib/chef/provider/cookbook_file.rb +100 -0
  65. data/lib/chef/provider/cron.rb +186 -0
  66. data/lib/chef/provider/cron/solaris.rb +195 -0
  67. data/lib/chef/provider/deploy.rb +343 -0
  68. data/lib/chef/provider/deploy/revision.rb +80 -0
  69. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  70. data/lib/chef/provider/directory.rb +72 -0
  71. data/lib/chef/provider/env.rb +152 -0
  72. data/lib/chef/provider/env/windows.rb +75 -0
  73. data/lib/chef/provider/erl_call.rb +101 -0
  74. data/lib/chef/provider/execute.rb +66 -0
  75. data/lib/chef/provider/file.rb +222 -0
  76. data/lib/chef/provider/git.rb +243 -0
  77. data/lib/chef/provider/group.rb +133 -0
  78. data/lib/chef/provider/group/aix.rb +70 -0
  79. data/lib/chef/provider/group/dscl.rb +121 -0
  80. data/lib/chef/provider/group/gpasswd.rb +53 -0
  81. data/lib/chef/provider/group/groupadd.rb +81 -0
  82. data/lib/chef/provider/group/pw.rb +84 -0
  83. data/lib/chef/provider/group/suse.rb +53 -0
  84. data/lib/chef/provider/group/usermod.rb +57 -0
  85. data/lib/chef/provider/group/windows.rb +79 -0
  86. data/lib/chef/provider/ifconfig.rb +134 -0
  87. data/lib/chef/provider/link.rb +164 -0
  88. data/lib/chef/provider/log.rb +54 -0
  89. data/lib/chef/provider/mdadm.rb +91 -0
  90. data/lib/chef/provider/mount.rb +114 -0
  91. data/lib/chef/provider/mount/mount.rb +240 -0
  92. data/lib/chef/provider/mount/windows.rb +81 -0
  93. data/lib/chef/provider/ohai.rb +42 -0
  94. data/lib/chef/provider/package.rb +163 -0
  95. data/lib/chef/provider/package/apt.rb +135 -0
  96. data/lib/chef/provider/package/dpkg.rb +115 -0
  97. data/lib/chef/provider/package/easy_install.rb +136 -0
  98. data/lib/chef/provider/package/freebsd.rb +125 -0
  99. data/lib/chef/provider/package/macports.rb +105 -0
  100. data/lib/chef/provider/package/pacman.rb +101 -0
  101. data/lib/chef/provider/package/portage.rb +135 -0
  102. data/lib/chef/provider/package/rpm.rb +104 -0
  103. data/lib/chef/provider/package/rubygems.rb +465 -0
  104. data/lib/chef/provider/package/solaris.rb +130 -0
  105. data/lib/chef/provider/package/yum-dump.py +286 -0
  106. data/lib/chef/provider/package/yum.rb +1128 -0
  107. data/lib/chef/provider/package/zypper.rb +144 -0
  108. data/lib/chef/provider/remote_directory.rb +137 -0
  109. data/lib/chef/provider/route.rb +193 -0
  110. data/lib/chef/provider/ruby_block.rb +34 -0
  111. data/lib/chef/provider/script.rb +55 -0
  112. data/lib/chef/provider/service.rb +122 -0
  113. data/lib/chef/provider/service/arch.rb +116 -0
  114. data/lib/chef/provider/service/debian.rb +130 -0
  115. data/lib/chef/provider/service/freebsd.rb +154 -0
  116. data/lib/chef/provider/service/gentoo.rb +53 -0
  117. data/lib/chef/provider/service/init.rb +71 -0
  118. data/lib/chef/provider/service/insserv.rb +52 -0
  119. data/lib/chef/provider/service/redhat.rb +60 -0
  120. data/lib/chef/provider/service/simple.rb +120 -0
  121. data/lib/chef/provider/service/solaris.rb +85 -0
  122. data/lib/chef/provider/service/systemd.rb +102 -0
  123. data/lib/chef/provider/service/upstart.rb +198 -0
  124. data/lib/chef/provider/service/windows.rb +146 -0
  125. data/lib/chef/provider/subversion.rb +197 -0
  126. data/lib/chef/provider/template.rb +104 -0
  127. data/lib/chef/provider/user.rb +186 -0
  128. data/lib/chef/provider/user/dscl.rb +280 -0
  129. data/lib/chef/provider/user/pw.rb +113 -0
  130. data/lib/chef/provider/user/useradd.rb +137 -0
  131. data/lib/chef/provider/user/windows.rb +124 -0
  132. data/lib/chef/providers.rb +93 -0
  133. data/lib/chef/recipe.rb +129 -0
  134. data/lib/chef/resource.rb +584 -0
  135. data/lib/chef/resource/apt_package.rb +34 -0
  136. data/lib/chef/resource/bash.rb +33 -0
  137. data/lib/chef/resource/breakpoint.rb +35 -0
  138. data/lib/chef/resource/cookbook_file.rb +45 -0
  139. data/lib/chef/resource/cron.rb +188 -0
  140. data/lib/chef/resource/csh.rb +33 -0
  141. data/lib/chef/resource/deploy.rb +380 -0
  142. data/lib/chef/resource/deploy_revision.rb +40 -0
  143. data/lib/chef/resource/directory.rb +89 -0
  144. data/lib/chef/resource/dpkg_package.rb +34 -0
  145. data/lib/chef/resource/easy_install_package.rb +57 -0
  146. data/lib/chef/resource/env.rb +58 -0
  147. data/lib/chef/resource/erl_call.rb +83 -0
  148. data/lib/chef/resource/execute.rb +127 -0
  149. data/lib/chef/resource/file.rb +112 -0
  150. data/lib/chef/resource/freebsd_package.rb +35 -0
  151. data/lib/chef/resource/gem_package.rb +53 -0
  152. data/lib/chef/resource/git.rb +46 -0
  153. data/lib/chef/resource/group.rb +70 -0
  154. data/lib/chef/resource/ifconfig.rb +134 -0
  155. data/lib/chef/resource/link.rb +105 -0
  156. data/lib/chef/resource/log.rb +62 -0
  157. data/lib/chef/resource/macports_package.rb +29 -0
  158. data/lib/chef/resource/mdadm.rb +82 -0
  159. data/lib/chef/resource/mount.rb +134 -0
  160. data/lib/chef/resource/ohai.rb +40 -0
  161. data/lib/chef/resource/package.rb +80 -0
  162. data/lib/chef/resource/pacman_package.rb +33 -0
  163. data/lib/chef/resource/perl.rb +33 -0
  164. data/lib/chef/resource/portage_package.rb +33 -0
  165. data/lib/chef/resource/python.rb +33 -0
  166. data/lib/chef/resource/remote_directory.rb +109 -0
  167. data/lib/chef/resource/route.rb +135 -0
  168. data/lib/chef/resource/rpm_package.rb +34 -0
  169. data/lib/chef/resource/ruby.rb +33 -0
  170. data/lib/chef/resource/ruby_block.rb +40 -0
  171. data/lib/chef/resource/scm.rb +147 -0
  172. data/lib/chef/resource/script.rb +60 -0
  173. data/lib/chef/resource/service.rb +160 -0
  174. data/lib/chef/resource/solaris_package.rb +36 -0
  175. data/lib/chef/resource/subversion.rb +36 -0
  176. data/lib/chef/resource/template.rb +69 -0
  177. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  178. data/lib/chef/resource/user.rb +130 -0
  179. data/lib/chef/resource/yum_package.rb +63 -0
  180. data/lib/chef/resource_collection.rb +217 -0
  181. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  182. data/lib/chef/resource_definition.rb +67 -0
  183. data/lib/chef/resource_definition_list.rb +38 -0
  184. data/lib/chef/resources.rb +62 -0
  185. data/lib/chef/role.rb +225 -0
  186. data/lib/chef/run_context.rb +126 -0
  187. data/lib/chef/run_list.rb +161 -0
  188. data/lib/chef/run_list/run_list_expansion.rb +159 -0
  189. data/lib/chef/run_list/run_list_item.rb +92 -0
  190. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  191. data/lib/chef/run_status.rb +121 -0
  192. data/lib/chef/runner.rb +105 -0
  193. data/lib/chef/shell_out.rb +250 -0
  194. data/lib/chef/shell_out/unix.rb +223 -0
  195. data/lib/chef/shell_out/windows.rb +98 -0
  196. data/lib/chef/tasks/chef_repo.rake +330 -0
  197. data/lib/chef/util/file_edit.rb +122 -0
  198. data/lib/chef/util/windows.rb +56 -0
  199. data/lib/chef/util/windows/net_group.rb +101 -0
  200. data/lib/chef/util/windows/net_use.rb +121 -0
  201. data/lib/chef/util/windows/net_user.rb +198 -0
  202. data/lib/chef/util/windows/volume.rb +59 -0
  203. data/lib/chef/version.rb +23 -0
  204. data/lib/chef/version_class.rb +70 -0
  205. data/lib/chef/version_constraint.rb +116 -0
  206. metadata +493 -0
@@ -0,0 +1,42 @@
1
+ # Author:: Lamont Granquist (<lamont@opscode.com>)
2
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+
19
+ #
20
+ # mixin to make this syntax work without specifying a source:
21
+ #
22
+ # gem_pacakge "/tmp/foo-x.y.z.gem"
23
+ # rpm_package "/tmp/foo-x.y-z.rpm"
24
+ # dpkg_package "/tmp/foo-x.y.z.deb"
25
+ #
26
+
27
+ class Chef
28
+ module Mixin
29
+ module GetSourceFromPackage
30
+ def initialize(new_resource, run_context)
31
+ super
32
+ # if we're passed something that looks like a filesystem path, with no source, use it
33
+ # - require at least one '/' in the path to avoid gem_package "foo" breaking if a file named 'foo' exists in the cwd
34
+ if new_resource.source.nil? && new_resource.package_name.match(/#{::File::SEPARATOR}/) && ::File.exists?(new_resource.package_name)
35
+ Chef::Log.debug("No package source specified, but #{new_resource.package_name} exists on the filesystem, copying to package source")
36
+ new_resource.source(@new_resource.package_name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,125 @@
1
+
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ class Chef
20
+ module Mixin
21
+ module Language
22
+
23
+ # Implementation class for determining platform dependent values
24
+ class PlatformDependentValue
25
+
26
+ # Create a platform dependent value object.
27
+ # === Arguments
28
+ # platform_hash (Hash) a hash of the same structure as Chef::Platform,
29
+ # like this:
30
+ # {
31
+ # :debian => {:default => 'the value for all debian'}
32
+ # [:centos, :redhat, :fedora] => {:default => "value for all EL variants"}
33
+ # :ubuntu => { :default => "default for ubuntu", '10.04' => "value for 10.04 only"},
34
+ # :default => "the default when nothing else matches"
35
+ # }
36
+ # * platforms can be specified as Symbols or Strings
37
+ # * multiple platforms can be grouped by using an Array as the key
38
+ # * values for platforms need to be Hashes of the form:
39
+ # {platform_version => value_for_that_version}
40
+ # * the exception to the above is the default value, which is given as
41
+ # :default => default_value
42
+ def initialize(platform_hash)
43
+ @values = {}
44
+ platform_hash.each { |platforms, value| set(platforms, value)}
45
+ end
46
+
47
+ def value_for_node(node)
48
+ platform, version = node[:platform].to_s, node[:platform_version].to_s
49
+ if @values.key?(platform) && @values[platform].key?(version)
50
+ @values[platform][version]
51
+ elsif @values.key?(platform) && @values[platform].key?("default")
52
+ @values[platform]["default"]
53
+ elsif @values.key?("default")
54
+ @values["default"]
55
+ else
56
+ nil
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def set(platforms, value)
63
+ if platforms.to_s == 'default'
64
+ @values["default"] = value
65
+ else
66
+ assert_valid_platform_values!(platforms, value)
67
+ Array(platforms).each { |platform| @values[platform.to_s] = normalize_keys(value)}
68
+ value
69
+ end
70
+ end
71
+
72
+ def normalize_keys(hash)
73
+ hash.inject({}) do |h, key_value|
74
+ keys, value = *key_value
75
+ Array(keys).each do |key|
76
+ h[key.to_s] = value
77
+ end
78
+ h
79
+ end
80
+ end
81
+
82
+ def assert_valid_platform_values!(platforms, value)
83
+ unless value.kind_of?(Hash)
84
+ msg = "platform dependent values must be specified in the format :platform => {:version => value} "
85
+ msg << "you gave a value #{value.inspect} for platform(s) #{platforms}"
86
+ raise ArgumentError, msg
87
+ end
88
+ end
89
+ end
90
+
91
+ # Given a hash similar to the one we use for Platforms, select a value from the hash. Supports
92
+ # per platform defaults, along with a single base default. Arrays may be passed as hash keys and
93
+ # will be expanded.
94
+ #
95
+ # === Parameters
96
+ # platform_hash:: A platform-style hash.
97
+ #
98
+ # === Returns
99
+ # value:: Whatever the most specific value of the hash is.
100
+ def value_for_platform(platform_hash)
101
+ PlatformDependentValue.new(platform_hash).value_for_node(node)
102
+ end
103
+
104
+ # Given a list of platforms, returns true if the current recipe is being run on a node with
105
+ # that platform, false otherwise.
106
+ #
107
+ # === Parameters
108
+ # args:: A list of platforms
109
+ #
110
+ # === Returns
111
+ # true:: If the current platform is in the list
112
+ # false:: If the current platform is not in the list
113
+ def platform?(*args)
114
+ has_platform = false
115
+
116
+ args.flatten.each do |platform|
117
+ has_platform = true if platform == node[:platform]
118
+ end
119
+
120
+ has_platform
121
+ end
122
+
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,61 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/log'
20
+
21
+ class Chef
22
+ module Mixin
23
+ module LanguageIncludeAttribute
24
+
25
+ # Loads the attribute file specified by the short name of the
26
+ # file, e.g., loads specified cookbook's
27
+ # "attributes/mailservers.rb"
28
+ # if passed
29
+ # "mailservers"
30
+ def include_attribute(*fully_qualified_attribute_short_filenames)
31
+ if self.kind_of?(Chef::Node)
32
+ node = self
33
+ else
34
+ node = @node
35
+ end
36
+
37
+ fully_qualified_attribute_short_filenames.flatten.each do |fully_qualified_attribute_short_filename|
38
+ if node.run_state[:seen_attributes].has_key?(fully_qualified_attribute_short_filename)
39
+ Chef::Log.debug("I am not loading attribute file #{fully_qualified_attribute_short_filename}, because I have already seen it.")
40
+ next
41
+ end
42
+
43
+ Chef::Log.debug("Loading Attribute #{fully_qualified_attribute_short_filename}")
44
+ node.run_state[:seen_attributes][fully_qualified_attribute_short_filename] = true
45
+
46
+ if amatch = fully_qualified_attribute_short_filename.match(/(.+?)::(.+)/)
47
+ cookbook_name = amatch[1].to_sym
48
+ node.load_attribute_by_short_filename(amatch[2], cookbook_name)
49
+ else
50
+ cookbook_name = fully_qualified_attribute_short_filename.to_sym
51
+ node.load_attribute_by_short_filename("default", cookbook_name)
52
+ end
53
+ end
54
+ true
55
+ end
56
+
57
+ end
58
+ end
59
+ end
60
+
61
+
@@ -0,0 +1,52 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008, 2009 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/log'
20
+
21
+ class Chef
22
+ module Mixin
23
+ module LanguageIncludeRecipe
24
+
25
+ def include_recipe(*recipe_names)
26
+ result_recipes = Array.new
27
+ recipe_names.flatten.each do |recipe_name|
28
+ if node.run_state[:seen_recipes].has_key?(recipe_name)
29
+ Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.")
30
+ next
31
+ end
32
+
33
+ Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe")
34
+ node.run_state[:seen_recipes][recipe_name] = true
35
+
36
+ cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
37
+
38
+ run_context = self.is_a?(Chef::RunContext) ? self : self.run_context
39
+ cookbook = run_context.cookbook_collection[cookbook_name]
40
+ result_recipes << cookbook.load_recipe(recipe_short_name, run_context)
41
+ end
42
+ result_recipes
43
+ end
44
+
45
+ def require_recipe(*args)
46
+ include_recipe(*args)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,225 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ class Chef
19
+
20
+ module Mixin
21
+ module ParamsValidate
22
+
23
+ # Takes a hash of options, along with a map to validate them. Returns the original
24
+ # options hash, plus any changes that might have been made (through things like setting
25
+ # default values in the validation map)
26
+ #
27
+ # For example:
28
+ #
29
+ # validate({ :one => "neat" }, { :one => { :kind_of => String }})
30
+ #
31
+ # Would raise an exception if the value of :one above is not a kind_of? string. Valid
32
+ # map options are:
33
+ #
34
+ # :default:: Sets the default value for this parameter.
35
+ # :callbacks:: Takes a hash of Procs, which should return true if the argument is valid.
36
+ # The key will be inserted into the error message if the Proc does not return true:
37
+ # "Option #{key}'s value #{value} #{message}!"
38
+ # :kind_of:: Ensure that the value is a kind_of?(Whatever). If passed an array, it will ensure
39
+ # that the value is one of those types.
40
+ # :respond_to:: Ensure that the value has a given method. Takes one method name or an array of
41
+ # method names.
42
+ # :required:: Raise an exception if this parameter is missing. Valid values are true or false,
43
+ # by default, options are not required.
44
+ # :regex:: Match the value of the paramater against a regular expression.
45
+ # :equal_to:: Match the value of the paramater with ==. An array means it can be equal to any
46
+ # of the values.
47
+ def validate(opts, map)
48
+ #--
49
+ # validate works by taking the keys in the validation map, assuming it's a hash, and
50
+ # looking for _pv_:symbol as methods. Assuming it find them, it calls the right
51
+ # one.
52
+ #++
53
+ raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
54
+ raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
55
+
56
+ map.each do |key, validation|
57
+ unless key.kind_of?(Symbol) || key.kind_of?(String)
58
+ raise ArgumentError, "Validation map keys must be symbols or strings!"
59
+ end
60
+ case validation
61
+ when true
62
+ _pv_required(opts, key)
63
+ when false
64
+ true
65
+ when Hash
66
+ validation.each do |check, carg|
67
+ check_method = "_pv_#{check.to_s}"
68
+ if self.respond_to?(check_method, true)
69
+ self.send(check_method, opts, key, carg)
70
+ else
71
+ raise ArgumentError, "Validation map has unknown check: #{check}"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ opts
77
+ end
78
+
79
+ def set_or_return(symbol, arg, validation)
80
+ iv_symbol = "@#{symbol.to_s}".to_sym
81
+ map = {
82
+ symbol => validation
83
+ }
84
+
85
+ if arg == nil && self.instance_variable_defined?(iv_symbol) == true
86
+ self.instance_variable_get(iv_symbol)
87
+ else
88
+ opts = validate({ symbol => arg }, { symbol => validation })
89
+ self.instance_variable_set(iv_symbol, opts[symbol])
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ # Return the value of a parameter, or nil if it doesn't exist.
96
+ def _pv_opts_lookup(opts, key)
97
+ if opts.has_key?(key.to_s)
98
+ opts[key.to_s]
99
+ elsif opts.has_key?(key.to_sym)
100
+ opts[key.to_sym]
101
+ else
102
+ nil
103
+ end
104
+ end
105
+
106
+ # Raise an exception if the parameter is not found.
107
+ def _pv_required(opts, key, is_required=true)
108
+ if is_required
109
+ if (opts.has_key?(key.to_s) && !opts[key.to_s].nil?) ||
110
+ (opts.has_key?(key.to_sym) && !opts[key.to_sym].nil?)
111
+ true
112
+ else
113
+ raise Exceptions::ValidationFailed, "Required argument #{key} is missing!"
114
+ end
115
+ end
116
+ end
117
+
118
+ def _pv_equal_to(opts, key, to_be)
119
+ value = _pv_opts_lookup(opts, key)
120
+ unless value.nil?
121
+ passes = false
122
+ Array(to_be).each do |tb|
123
+ passes = true if value == tb
124
+ end
125
+ unless passes
126
+ raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
127
+ end
128
+ end
129
+ end
130
+
131
+ # Raise an exception if the parameter is not a kind_of?(to_be)
132
+ def _pv_kind_of(opts, key, to_be)
133
+ value = _pv_opts_lookup(opts, key)
134
+ unless value.nil?
135
+ passes = false
136
+ Array(to_be).each do |tb|
137
+ passes = true if value.kind_of?(tb)
138
+ end
139
+ unless passes
140
+ raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
141
+ end
142
+ end
143
+ end
144
+
145
+ # Raise an exception if the parameter does not respond to a given set of methods.
146
+ def _pv_respond_to(opts, key, method_name_list)
147
+ value = _pv_opts_lookup(opts, key)
148
+ unless value.nil?
149
+ Array(method_name_list).each do |method_name|
150
+ unless value.respond_to?(method_name)
151
+ raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ # Assert that parameter returns false when passed a predicate method.
158
+ # For example, :cannot_be => :blank will raise a Exceptions::ValidationFailed
159
+ # error value.blank? returns a 'truthy' (not nil or false) value.
160
+ #
161
+ # Note, this will *PASS* if the object doesn't respond to the method.
162
+ # So, to make sure a value is not nil and not blank, you need to do
163
+ # both :cannot_be => :blank *and* :cannot_be => :nil (or :required => true)
164
+ def _pv_cannot_be(opts, key, predicate_method_base_name)
165
+ value = _pv_opts_lookup(opts, key)
166
+ predicate_method = (predicate_method_base_name.to_s + "?").to_sym
167
+
168
+ if value.respond_to?(predicate_method)
169
+ if value.send(predicate_method)
170
+ raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
171
+ end
172
+ end
173
+ end
174
+
175
+ # Assign a default value to a parameter.
176
+ def _pv_default(opts, key, default_value)
177
+ value = _pv_opts_lookup(opts, key)
178
+ if value == nil
179
+ opts[key] = default_value
180
+ end
181
+ end
182
+
183
+ # Check a parameter against a regular expression.
184
+ def _pv_regex(opts, key, regex)
185
+ value = _pv_opts_lookup(opts, key)
186
+ if value != nil
187
+ passes = false
188
+ [ regex ].flatten.each do |r|
189
+ if value != nil
190
+ if r.match(value.to_s)
191
+ passes = true
192
+ end
193
+ end
194
+ end
195
+ unless passes
196
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
197
+ end
198
+ end
199
+ end
200
+
201
+ # Check a parameter against a hash of proc's.
202
+ def _pv_callbacks(opts, key, callbacks)
203
+ raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
204
+ value = _pv_opts_lookup(opts, key)
205
+ if value != nil
206
+ callbacks.each do |message, zeproc|
207
+ if zeproc.call(value) != true
208
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ # Allow a parameter to default to @name
215
+ def _pv_name_attribute(opts, key, is_name_attribute=true)
216
+ if is_name_attribute
217
+ if opts[key] == nil
218
+ opts[key] = self.instance_variable_get("@name")
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+