cheffish 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -0
  3. data/LICENSE +201 -201
  4. data/README.md +120 -120
  5. data/Rakefile +23 -23
  6. data/cheffish.gemspec +26 -0
  7. data/lib/chef/provider/chef_acl.rb +446 -439
  8. data/lib/chef/provider/chef_client.rb +53 -53
  9. data/lib/chef/provider/chef_container.rb +55 -55
  10. data/lib/chef/provider/chef_data_bag.rb +55 -55
  11. data/lib/chef/provider/chef_data_bag_item.rb +278 -278
  12. data/lib/chef/provider/chef_environment.rb +83 -83
  13. data/lib/chef/provider/chef_group.rb +83 -83
  14. data/lib/chef/provider/chef_mirror.rb +169 -169
  15. data/lib/chef/provider/chef_node.rb +87 -87
  16. data/lib/chef/provider/chef_organization.rb +155 -155
  17. data/lib/chef/provider/chef_resolved_cookbooks.rb +46 -46
  18. data/lib/chef/provider/chef_role.rb +84 -84
  19. data/lib/chef/provider/chef_user.rb +59 -59
  20. data/lib/chef/provider/private_key.rb +225 -225
  21. data/lib/chef/provider/public_key.rb +88 -88
  22. data/lib/chef/resource/chef_acl.rb +69 -69
  23. data/lib/chef/resource/chef_client.rb +48 -48
  24. data/lib/chef/resource/chef_container.rb +22 -22
  25. data/lib/chef/resource/chef_data_bag.rb +22 -22
  26. data/lib/chef/resource/chef_data_bag_item.rb +121 -121
  27. data/lib/chef/resource/chef_environment.rb +77 -77
  28. data/lib/chef/resource/chef_group.rb +53 -53
  29. data/lib/chef/resource/chef_mirror.rb +52 -52
  30. data/lib/chef/resource/chef_node.rb +22 -22
  31. data/lib/chef/resource/chef_organization.rb +69 -69
  32. data/lib/chef/resource/chef_resolved_cookbooks.rb +35 -35
  33. data/lib/chef/resource/chef_role.rb +110 -110
  34. data/lib/chef/resource/chef_user.rb +56 -56
  35. data/lib/chef/resource/private_key.rb +48 -48
  36. data/lib/chef/resource/public_key.rb +25 -25
  37. data/lib/cheffish.rb +235 -235
  38. data/lib/cheffish/actor_provider_base.rb +131 -131
  39. data/lib/cheffish/basic_chef_client.rb +184 -184
  40. data/lib/cheffish/chef_provider_base.rb +246 -246
  41. data/lib/cheffish/chef_run.rb +162 -162
  42. data/lib/cheffish/chef_run_data.rb +19 -19
  43. data/lib/cheffish/chef_run_listener.rb +30 -30
  44. data/lib/cheffish/key_formatter.rb +113 -113
  45. data/lib/cheffish/merged_config.rb +98 -94
  46. data/lib/cheffish/recipe_dsl.rb +157 -157
  47. data/lib/cheffish/rspec.rb +8 -8
  48. data/lib/cheffish/rspec/chef_run_support.rb +83 -83
  49. data/lib/cheffish/rspec/matchers.rb +4 -4
  50. data/lib/cheffish/rspec/matchers/be_idempotent.rb +16 -16
  51. data/lib/cheffish/rspec/matchers/emit_no_warnings_or_errors.rb +15 -15
  52. data/lib/cheffish/rspec/matchers/have_updated.rb +37 -37
  53. data/lib/cheffish/rspec/matchers/partially_match.rb +63 -63
  54. data/lib/cheffish/rspec/recipe_run_wrapper.rb +78 -78
  55. data/lib/cheffish/rspec/repository_support.rb +108 -108
  56. data/lib/cheffish/server_api.rb +52 -52
  57. data/lib/cheffish/version.rb +3 -3
  58. data/lib/cheffish/with_pattern.rb +21 -21
  59. data/spec/functional/fingerprint_spec.rb +64 -64
  60. data/spec/functional/merged_config_spec.rb +19 -19
  61. data/spec/functional/server_api_spec.rb +13 -13
  62. data/spec/integration/chef_acl_spec.rb +892 -879
  63. data/spec/integration/chef_client_spec.rb +105 -105
  64. data/spec/integration/chef_container_spec.rb +33 -33
  65. data/spec/integration/chef_group_spec.rb +309 -309
  66. data/spec/integration/chef_mirror_spec.rb +491 -491
  67. data/spec/integration/chef_node_spec.rb +786 -786
  68. data/spec/integration/chef_organization_spec.rb +226 -226
  69. data/spec/integration/chef_role_spec.rb +78 -78
  70. data/spec/integration/chef_user_spec.rb +85 -85
  71. data/spec/integration/private_key_spec.rb +399 -399
  72. data/spec/integration/recipe_dsl_spec.rb +28 -28
  73. data/spec/integration/rspec/converge_spec.rb +183 -183
  74. data/spec/support/key_support.rb +29 -29
  75. data/spec/support/spec_support.rb +15 -15
  76. data/spec/unit/get_private_key_spec.rb +131 -131
  77. data/spec/unit/recipe_run_wrapper_spec.rb +37 -37
  78. metadata +7 -5
@@ -1,94 +1,98 @@
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_h
91
+ to_hash
92
+ end
93
+
94
+ def to_s
95
+ to_hash.to_s
96
+ end
97
+ end
98
+ 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