cheffish 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/README.md +120 -117
  4. data/Rakefile +23 -23
  5. data/lib/chef/provider/chef_acl.rb +439 -434
  6. data/lib/chef/provider/chef_client.rb +53 -48
  7. data/lib/chef/provider/chef_container.rb +55 -50
  8. data/lib/chef/provider/chef_data_bag.rb +55 -50
  9. data/lib/chef/provider/chef_data_bag_item.rb +278 -273
  10. data/lib/chef/provider/chef_environment.rb +83 -78
  11. data/lib/chef/provider/chef_group.rb +83 -78
  12. data/lib/chef/provider/chef_mirror.rb +169 -164
  13. data/lib/chef/provider/chef_node.rb +87 -82
  14. data/lib/chef/provider/chef_organization.rb +155 -150
  15. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -41
  16. data/lib/chef/provider/chef_role.rb +84 -79
  17. data/lib/chef/provider/chef_user.rb +59 -54
  18. data/lib/chef/provider/private_key.rb +225 -220
  19. data/lib/chef/provider/public_key.rb +88 -82
  20. data/lib/chef/resource/chef_acl.rb +69 -65
  21. data/lib/chef/resource/chef_client.rb +48 -44
  22. data/lib/chef/resource/chef_container.rb +22 -18
  23. data/lib/chef/resource/chef_data_bag.rb +22 -18
  24. data/lib/chef/resource/chef_data_bag_item.rb +121 -114
  25. data/lib/chef/resource/chef_environment.rb +77 -71
  26. data/lib/chef/resource/chef_group.rb +53 -49
  27. data/lib/chef/resource/chef_mirror.rb +52 -48
  28. data/lib/chef/resource/chef_node.rb +22 -18
  29. data/lib/chef/resource/chef_organization.rb +69 -64
  30. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -31
  31. data/lib/chef/resource/chef_role.rb +110 -104
  32. data/lib/chef/resource/chef_user.rb +56 -52
  33. data/lib/chef/resource/private_key.rb +48 -44
  34. data/lib/chef/resource/public_key.rb +25 -21
  35. data/lib/cheffish.rb +235 -233
  36. data/lib/cheffish/actor_provider_base.rb +131 -131
  37. data/lib/cheffish/basic_chef_client.rb +184 -184
  38. data/lib/cheffish/chef_provider_base.rb +246 -246
  39. data/lib/cheffish/chef_run.rb +162 -155
  40. data/lib/cheffish/chef_run_data.rb +19 -19
  41. data/lib/cheffish/chef_run_listener.rb +30 -30
  42. data/lib/cheffish/key_formatter.rb +113 -113
  43. data/lib/cheffish/merged_config.rb +94 -94
  44. data/lib/cheffish/recipe_dsl.rb +157 -157
  45. data/lib/cheffish/rspec.rb +8 -8
  46. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  47. data/lib/cheffish/rspec/matchers.rb +4 -4
  48. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  49. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  50. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  51. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  52. data/lib/cheffish/rspec/recipe_run_wrapper.rb +59 -47
  53. data/lib/cheffish/rspec/repository_support.rb +108 -108
  54. data/lib/cheffish/server_api.rb +52 -52
  55. data/lib/cheffish/version.rb +3 -3
  56. data/lib/cheffish/with_pattern.rb +21 -21
  57. data/spec/functional/fingerprint_spec.rb +64 -64
  58. data/spec/functional/merged_config_spec.rb +19 -19
  59. data/spec/functional/server_api_spec.rb +13 -13
  60. data/spec/integration/chef_acl_spec.rb +879 -879
  61. data/spec/integration/chef_client_spec.rb +105 -105
  62. data/spec/integration/chef_container_spec.rb +33 -33
  63. data/spec/integration/chef_group_spec.rb +309 -309
  64. data/spec/integration/chef_mirror_spec.rb +491 -491
  65. data/spec/integration/chef_node_spec.rb +786 -786
  66. data/spec/integration/chef_organization_spec.rb +226 -226
  67. data/spec/integration/chef_role_spec.rb +78 -0
  68. data/spec/integration/chef_user_spec.rb +85 -85
  69. data/spec/integration/private_key_spec.rb +399 -399
  70. data/spec/integration/recipe_dsl_spec.rb +28 -28
  71. data/spec/integration/rspec/converge_spec.rb +183 -183
  72. data/spec/support/key_support.rb +29 -29
  73. data/spec/support/spec_support.rb +15 -15
  74. data/spec/unit/get_private_key_spec.rb +131 -131
  75. data/spec/unit/recipe_run_wrapper_spec.rb +37 -0
  76. metadata +8 -5
@@ -1,94 +1,94 @@
1
- module Cheffish
2
- class MergedConfig
3
- def initialize(*configs)
4
- @configs = configs
5
- @merge_arrays = {}
6
- end
7
-
8
- include Enumerable
9
-
10
- attr_reader :configs
11
- def merge_arrays(*symbols)
12
- if symbols.size > 0
13
- symbols.each do |symbol|
14
- @merge_arrays[symbol] = true
15
- end
16
- else
17
- @merge_arrays
18
- end
19
- end
20
-
21
- def [](name)
22
- if @merge_arrays[name]
23
- configs.select { |c| !c[name].nil? }.collect_concat { |c| c[name] }
24
- else
25
- result_configs = []
26
- configs.each do |config|
27
- value = config[name]
28
- if !value.nil?
29
- if value.respond_to?(:keys)
30
- result_configs << value
31
- elsif result_configs.size > 0
32
- return result_configs[0]
33
- else
34
- return value
35
- end
36
- end
37
- end
38
- if result_configs.size > 1
39
- MergedConfig.new(*result_configs)
40
- elsif result_configs.size == 1
41
- result_configs[0]
42
- else
43
- nil
44
- end
45
- end
46
- end
47
-
48
- def method_missing(name, *args)
49
- if args.count > 0
50
- raise NoMethodError, "Unexpected method #{name} for MergedConfig with arguments #{args}"
51
- else
52
- self[name]
53
- end
54
- end
55
-
56
- def key?(name)
57
- configs.any? { |config| config.has_key?(name) }
58
- end
59
-
60
- alias_method :has_key?, :key?
61
-
62
- def keys
63
- configs.map { |c| c.keys }.flatten(1).uniq
64
- end
65
-
66
- def values
67
- keys.map { |key| self[key] }
68
- end
69
-
70
- def each_pair(&block)
71
- each(&block)
72
- end
73
-
74
- def each
75
- keys.each do |key|
76
- if block_given?
77
- yield key, self[key]
78
- end
79
- end
80
- end
81
-
82
- def to_hash
83
- result = {}
84
- each_pair do |key, value|
85
- result[key] = value
86
- end
87
- result
88
- end
89
-
90
- def to_s
91
- to_hash.to_s
92
- end
93
- end
94
- end
1
+ module Cheffish
2
+ class MergedConfig
3
+ def initialize(*configs)
4
+ @configs = configs
5
+ @merge_arrays = {}
6
+ end
7
+
8
+ include Enumerable
9
+
10
+ attr_reader :configs
11
+ def merge_arrays(*symbols)
12
+ if symbols.size > 0
13
+ symbols.each do |symbol|
14
+ @merge_arrays[symbol] = true
15
+ end
16
+ else
17
+ @merge_arrays
18
+ end
19
+ end
20
+
21
+ def [](name)
22
+ if @merge_arrays[name]
23
+ configs.select { |c| !c[name].nil? }.collect_concat { |c| c[name] }
24
+ else
25
+ result_configs = []
26
+ configs.each do |config|
27
+ value = config[name]
28
+ if !value.nil?
29
+ if value.respond_to?(:keys)
30
+ result_configs << value
31
+ elsif result_configs.size > 0
32
+ return result_configs[0]
33
+ else
34
+ return value
35
+ end
36
+ end
37
+ end
38
+ if result_configs.size > 1
39
+ MergedConfig.new(*result_configs)
40
+ elsif result_configs.size == 1
41
+ result_configs[0]
42
+ else
43
+ nil
44
+ end
45
+ end
46
+ end
47
+
48
+ def method_missing(name, *args)
49
+ if args.count > 0
50
+ raise NoMethodError, "Unexpected method #{name} for MergedConfig with arguments #{args}"
51
+ else
52
+ self[name]
53
+ end
54
+ end
55
+
56
+ def key?(name)
57
+ configs.any? { |config| config.has_key?(name) }
58
+ end
59
+
60
+ alias_method :has_key?, :key?
61
+
62
+ def keys
63
+ configs.map { |c| c.keys }.flatten(1).uniq
64
+ end
65
+
66
+ def values
67
+ keys.map { |key| self[key] }
68
+ end
69
+
70
+ def each_pair(&block)
71
+ each(&block)
72
+ end
73
+
74
+ def each
75
+ keys.each do |key|
76
+ if block_given?
77
+ yield key, self[key]
78
+ end
79
+ end
80
+ end
81
+
82
+ def to_hash
83
+ result = {}
84
+ each_pair do |key, value|
85
+ result[key] = value
86
+ end
87
+ result
88
+ end
89
+
90
+ def to_s
91
+ to_hash.to_s
92
+ end
93
+ end
94
+ end
@@ -1,157 +1,157 @@
1
- require 'cheffish'
2
-
3
- require 'chef/version'
4
- require 'chef_zero/server'
5
- require 'chef/chef_fs/chef_fs_data_store'
6
- require 'chef/chef_fs/config'
7
- require 'cheffish/chef_run_data'
8
- require 'cheffish/chef_run_listener'
9
- require 'chef/client'
10
- require 'chef/config'
11
- require 'chef_zero/version'
12
- require 'cheffish/merged_config'
13
- require 'chef/resource/chef_acl'
14
- require 'chef/resource/chef_client'
15
- require 'chef/resource/chef_container'
16
- require 'chef/resource/chef_data_bag'
17
- require 'chef/resource/chef_data_bag_item'
18
- require 'chef/resource/chef_environment'
19
- require 'chef/resource/chef_group'
20
- require 'chef/resource/chef_mirror'
21
- require 'chef/resource/chef_node'
22
- require 'chef/resource/chef_organization'
23
- require 'chef/resource/chef_role'
24
- require 'chef/resource/chef_user'
25
- require 'chef/resource/private_key'
26
- require 'chef/resource/public_key'
27
- require 'chef/provider/chef_acl'
28
- require 'chef/provider/chef_client'
29
- require 'chef/provider/chef_container'
30
- require 'chef/provider/chef_data_bag'
31
- require 'chef/provider/chef_data_bag_item'
32
- require 'chef/provider/chef_environment'
33
- require 'chef/provider/chef_group'
34
- require 'chef/provider/chef_mirror'
35
- require 'chef/provider/chef_node'
36
- require 'chef/provider/chef_organization'
37
- require 'chef/provider/chef_role'
38
- require 'chef/provider/chef_user'
39
- require 'chef/provider/private_key'
40
- require 'chef/provider/public_key'
41
-
42
-
43
- class Chef
44
- module DSL
45
- module Recipe
46
- def with_chef_data_bag(name)
47
- run_context.cheffish.with_data_bag(name, &block)
48
- end
49
-
50
- def with_chef_environment(name, &block)
51
- run_context.cheffish.with_environment(name, &block)
52
- end
53
-
54
- def with_chef_data_bag_item_encryption(encryption_options, &block)
55
- run_context.cheffish.with_data_bag_item_encryption(encryption_options, &block)
56
- end
57
-
58
- def with_chef_server(server_url, options = {}, &block)
59
- run_context.cheffish.with_chef_server({ :chef_server_url => server_url, :options => options }, &block)
60
- end
61
-
62
- def with_chef_local_server(options, &block)
63
- options[:host] ||= '127.0.0.1'
64
- options[:log_level] ||= Chef::Log.level
65
- options[:port] ||= ChefZero::VERSION.to_f >= 2.2 ? 8901.upto(9900) : 8901
66
-
67
- # Create the data store chef-zero will use
68
- options[:data_store] ||= begin
69
- if !options[:chef_repo_path]
70
- raise "chef_repo_path must be specified to with_chef_local_server"
71
- end
72
-
73
- # Ensure all paths are given
74
- %w(acl client cookbook container data_bag environment group node role).each do |type|
75
- # Set the options as symbol keys and then copy to string keys
76
- string_key = "#{type}_path"
77
- symbol_key = "#{type}_path".to_sym
78
-
79
- options[symbol_key] ||= begin
80
- if options[:chef_repo_path].kind_of?(String)
81
- Chef::Util::PathHelper.join(options[:chef_repo_path], "#{type}s")
82
- else
83
- options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s")}
84
- end
85
- end
86
-
87
- # Copy over to string keys for things that use string keys (ChefFS)...
88
- # TODO: Fix ChefFS to take symbols or use something that is insensitive to the difference
89
- options[string_key] = options[symbol_key]
90
- end
91
-
92
- chef_fs = Chef::ChefFS::Config.new(options).local_fs
93
- chef_fs.write_pretty_json = true
94
- Chef::ChefFS::ChefFSDataStore.new(chef_fs)
95
- end
96
-
97
- # Start the chef-zero server
98
- Chef::Log.info("Starting chef-zero on port #{options[:port]} with repository at #{options[:data_store].chef_fs.fs_description}")
99
- chef_zero_server = ChefZero::Server.new(options)
100
- chef_zero_server.start_background
101
-
102
- run_context.cheffish.local_servers << chef_zero_server
103
-
104
- with_chef_server(chef_zero_server.url, &block)
105
- end
106
-
107
- def get_private_key(name)
108
- Cheffish.get_private_key(name, run_context.config)
109
- end
110
- end
111
- end
112
-
113
- class Config
114
- default(:profile) { ENV['CHEF_PROFILE'] || 'default' }
115
- configurable(:private_keys)
116
- default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, 'keys'), Chef::Util::PathHelper.join(user_home, '.ssh') ] }
117
- default(:private_key_write_path) { private_key_paths.first }
118
- end
119
-
120
- class RunContext
121
- def cheffish
122
- node.run_state[:cheffish] ||= begin
123
- run_data = Cheffish::ChefRunData.new(config)
124
- events.register(Cheffish::ChefRunListener.new(node))
125
- run_data
126
- end
127
- end
128
-
129
- def config
130
- node.run_state[:chef_config] ||= Cheffish.profiled_config(Chef::Config)
131
- end
132
- end
133
-
134
- Chef::Client.when_run_starts do |run_status|
135
- # Pulling on cheffish_run_data makes it initialize right now
136
- run_status.node.run_state[:chef_config] = config = Cheffish.profiled_config(Chef::Config)
137
- run_status.node.run_state[:cheffish] = run_data = Cheffish::ChefRunData.new(config)
138
- run_status.events.register(Cheffish::ChefRunListener.new(run_status.node))
139
- end
140
-
141
- end
142
-
143
- # Chef 12 moved Chef::Config.path_join to PathHelper.join
144
- if Chef::VERSION.to_i >= 12
145
- require 'chef/util/path_helper'
146
- else
147
- require 'chef/config'
148
- class Chef
149
- class Util
150
- class PathHelper
151
- def self.join(*args)
152
- Chef::Config.path_join(*args)
153
- end
154
- end
155
- end
156
- end
157
- end
1
+ require 'cheffish'
2
+
3
+ require 'chef/version'
4
+ require 'chef_zero/server'
5
+ require 'chef/chef_fs/chef_fs_data_store'
6
+ require 'chef/chef_fs/config'
7
+ require 'cheffish/chef_run_data'
8
+ require 'cheffish/chef_run_listener'
9
+ require 'chef/client'
10
+ require 'chef/config'
11
+ require 'chef_zero/version'
12
+ require 'cheffish/merged_config'
13
+ require 'chef/resource/chef_acl'
14
+ require 'chef/resource/chef_client'
15
+ require 'chef/resource/chef_container'
16
+ require 'chef/resource/chef_data_bag'
17
+ require 'chef/resource/chef_data_bag_item'
18
+ require 'chef/resource/chef_environment'
19
+ require 'chef/resource/chef_group'
20
+ require 'chef/resource/chef_mirror'
21
+ require 'chef/resource/chef_node'
22
+ require 'chef/resource/chef_organization'
23
+ require 'chef/resource/chef_role'
24
+ require 'chef/resource/chef_user'
25
+ require 'chef/resource/private_key'
26
+ require 'chef/resource/public_key'
27
+ require 'chef/provider/chef_acl'
28
+ require 'chef/provider/chef_client'
29
+ require 'chef/provider/chef_container'
30
+ require 'chef/provider/chef_data_bag'
31
+ require 'chef/provider/chef_data_bag_item'
32
+ require 'chef/provider/chef_environment'
33
+ require 'chef/provider/chef_group'
34
+ require 'chef/provider/chef_mirror'
35
+ require 'chef/provider/chef_node'
36
+ require 'chef/provider/chef_organization'
37
+ require 'chef/provider/chef_role'
38
+ require 'chef/provider/chef_user'
39
+ require 'chef/provider/private_key'
40
+ require 'chef/provider/public_key'
41
+
42
+
43
+ class Chef
44
+ module DSL
45
+ module Recipe
46
+ def with_chef_data_bag(name)
47
+ run_context.cheffish.with_data_bag(name, &block)
48
+ end
49
+
50
+ def with_chef_environment(name, &block)
51
+ run_context.cheffish.with_environment(name, &block)
52
+ end
53
+
54
+ def with_chef_data_bag_item_encryption(encryption_options, &block)
55
+ run_context.cheffish.with_data_bag_item_encryption(encryption_options, &block)
56
+ end
57
+
58
+ def with_chef_server(server_url, options = {}, &block)
59
+ run_context.cheffish.with_chef_server({ :chef_server_url => server_url, :options => options }, &block)
60
+ end
61
+
62
+ def with_chef_local_server(options, &block)
63
+ options[:host] ||= '127.0.0.1'
64
+ options[:log_level] ||= Chef::Log.level
65
+ options[:port] ||= ChefZero::VERSION.to_f >= 2.2 ? 8901.upto(9900) : 8901
66
+
67
+ # Create the data store chef-zero will use
68
+ options[:data_store] ||= begin
69
+ if !options[:chef_repo_path]
70
+ raise "chef_repo_path must be specified to with_chef_local_server"
71
+ end
72
+
73
+ # Ensure all paths are given
74
+ %w(acl client cookbook container data_bag environment group node role).each do |type|
75
+ # Set the options as symbol keys and then copy to string keys
76
+ string_key = "#{type}_path"
77
+ symbol_key = "#{type}_path".to_sym
78
+
79
+ options[symbol_key] ||= begin
80
+ if options[:chef_repo_path].kind_of?(String)
81
+ Chef::Util::PathHelper.join(options[:chef_repo_path], "#{type}s")
82
+ else
83
+ options[:chef_repo_path].map { |path| Chef::Util::PathHelper.join(path, "#{type}s")}
84
+ end
85
+ end
86
+
87
+ # Copy over to string keys for things that use string keys (ChefFS)...
88
+ # TODO: Fix ChefFS to take symbols or use something that is insensitive to the difference
89
+ options[string_key] = options[symbol_key]
90
+ end
91
+
92
+ chef_fs = Chef::ChefFS::Config.new(options).local_fs
93
+ chef_fs.write_pretty_json = true
94
+ Chef::ChefFS::ChefFSDataStore.new(chef_fs)
95
+ end
96
+
97
+ # Start the chef-zero server
98
+ Chef::Log.info("Starting chef-zero on port #{options[:port]} with repository at #{options[:data_store].chef_fs.fs_description}")
99
+ chef_zero_server = ChefZero::Server.new(options)
100
+ chef_zero_server.start_background
101
+
102
+ run_context.cheffish.local_servers << chef_zero_server
103
+
104
+ with_chef_server(chef_zero_server.url, &block)
105
+ end
106
+
107
+ def get_private_key(name)
108
+ Cheffish.get_private_key(name, run_context.config)
109
+ end
110
+ end
111
+ end
112
+
113
+ class Config
114
+ default(:profile) { ENV['CHEF_PROFILE'] || 'default' }
115
+ configurable(:private_keys)
116
+ default(:private_key_paths) { [ Chef::Util::PathHelper.join(config_dir, 'keys'), Chef::Util::PathHelper.join(user_home, '.ssh') ] }
117
+ default(:private_key_write_path) { private_key_paths.first }
118
+ end
119
+
120
+ class RunContext
121
+ def cheffish
122
+ node.run_state[:cheffish] ||= begin
123
+ run_data = Cheffish::ChefRunData.new(config)
124
+ events.register(Cheffish::ChefRunListener.new(node))
125
+ run_data
126
+ end
127
+ end
128
+
129
+ def config
130
+ node.run_state[:chef_config] ||= Cheffish.profiled_config(Chef::Config)
131
+ end
132
+ end
133
+
134
+ Chef::Client.when_run_starts do |run_status|
135
+ # Pulling on cheffish_run_data makes it initialize right now
136
+ run_status.node.run_state[:chef_config] = config = Cheffish.profiled_config(Chef::Config)
137
+ run_status.node.run_state[:cheffish] = run_data = Cheffish::ChefRunData.new(config)
138
+ run_status.events.register(Cheffish::ChefRunListener.new(run_status.node))
139
+ end
140
+
141
+ end
142
+
143
+ # Chef 12 moved Chef::Config.path_join to PathHelper.join
144
+ if Chef::VERSION.to_i >= 12
145
+ require 'chef/util/path_helper'
146
+ else
147
+ require 'chef/config'
148
+ class Chef
149
+ class Util
150
+ class PathHelper
151
+ def self.join(*args)
152
+ Chef::Config.path_join(*args)
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end