cheffish 1.5.0 → 1.6.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 (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