cheffish 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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,78 +1,83 @@
1
- require 'cheffish/chef_provider_base'
2
- require 'chef/resource/chef_environment'
3
- require 'chef/chef_fs/data_handler/environment_data_handler'
4
-
5
- class Chef::Provider::ChefEnvironment < Cheffish::ChefProviderBase
6
-
7
- def whyrun_supported?
8
- true
9
- end
10
-
11
- action :create do
12
- differences = json_differences(current_json, new_json)
13
-
14
- if current_resource_exists?
15
- if differences.size > 0
16
- description = [ "update environment #{new_resource.name} at #{rest.url}" ] + differences
17
- converge_by description do
18
- rest.put("environments/#{new_resource.name}", normalize_for_put(new_json))
19
- end
20
- end
21
- else
22
- description = [ "create environment #{new_resource.name} at #{rest.url}" ] + differences
23
- converge_by description do
24
- rest.post("environments", normalize_for_post(new_json))
25
- end
26
- end
27
- end
28
-
29
- action :delete do
30
- if current_resource_exists?
31
- converge_by "delete environment #{new_resource.name} at #{rest.url}" do
32
- rest.delete("environments/#{new_resource.name}")
33
- end
34
- end
35
- end
36
-
37
- def load_current_resource
38
- begin
39
- @current_resource = json_to_resource(rest.get("environments/#{new_resource.name}"))
40
- rescue Net::HTTPServerException => e
41
- if e.response.code == "404"
42
- @current_resource = not_found_resource
43
- else
44
- raise
45
- end
46
- end
47
- end
48
-
49
- def augment_new_json(json)
50
- # Apply modifiers
51
- json['default_attributes'] = apply_modifiers(new_resource.default_attribute_modifiers, json['default_attributes'])
52
- json['override_attributes'] = apply_modifiers(new_resource.override_attribute_modifiers, json['override_attributes'])
53
- json
54
- end
55
-
56
- #
57
- # Helpers
58
- #
59
-
60
- def resource_class
61
- Chef::Resource::ChefEnvironment
62
- end
63
-
64
- def data_handler
65
- Chef::ChefFS::DataHandler::EnvironmentDataHandler.new
66
- end
67
-
68
- def keys
69
- {
70
- 'name' => :name,
71
- 'description' => :description,
72
- 'cookbook_versions' => :cookbook_versions,
73
- 'default_attributes' => :default_attributes,
74
- 'override_attributes' => :override_attributes
75
- }
76
- end
77
-
78
- end
1
+ require 'cheffish/chef_provider_base'
2
+ require 'chef/resource/chef_environment'
3
+ require 'chef/chef_fs/data_handler/environment_data_handler'
4
+
5
+ class Chef
6
+ class Provider
7
+ class ChefEnvironment < Cheffish::ChefProviderBase
8
+ provides :chef_environment
9
+
10
+ def whyrun_supported?
11
+ true
12
+ end
13
+
14
+ action :create do
15
+ differences = json_differences(current_json, new_json)
16
+
17
+ if current_resource_exists?
18
+ if differences.size > 0
19
+ description = [ "update environment #{new_resource.name} at #{rest.url}" ] + differences
20
+ converge_by description do
21
+ rest.put("environments/#{new_resource.name}", normalize_for_put(new_json))
22
+ end
23
+ end
24
+ else
25
+ description = [ "create environment #{new_resource.name} at #{rest.url}" ] + differences
26
+ converge_by description do
27
+ rest.post("environments", normalize_for_post(new_json))
28
+ end
29
+ end
30
+ end
31
+
32
+ action :delete do
33
+ if current_resource_exists?
34
+ converge_by "delete environment #{new_resource.name} at #{rest.url}" do
35
+ rest.delete("environments/#{new_resource.name}")
36
+ end
37
+ end
38
+ end
39
+
40
+ def load_current_resource
41
+ begin
42
+ @current_resource = json_to_resource(rest.get("environments/#{new_resource.name}"))
43
+ rescue Net::HTTPServerException => e
44
+ if e.response.code == "404"
45
+ @current_resource = not_found_resource
46
+ else
47
+ raise
48
+ end
49
+ end
50
+ end
51
+
52
+ def augment_new_json(json)
53
+ # Apply modifiers
54
+ json['default_attributes'] = apply_modifiers(new_resource.default_attribute_modifiers, json['default_attributes'])
55
+ json['override_attributes'] = apply_modifiers(new_resource.override_attribute_modifiers, json['override_attributes'])
56
+ json
57
+ end
58
+
59
+ #
60
+ # Helpers
61
+ #
62
+
63
+ def resource_class
64
+ Chef::Resource::ChefEnvironment
65
+ end
66
+
67
+ def data_handler
68
+ Chef::ChefFS::DataHandler::EnvironmentDataHandler.new
69
+ end
70
+
71
+ def keys
72
+ {
73
+ 'name' => :name,
74
+ 'description' => :description,
75
+ 'cookbook_versions' => :cookbook_versions,
76
+ 'default_attributes' => :default_attributes,
77
+ 'override_attributes' => :override_attributes
78
+ }
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -1,78 +1,83 @@
1
- require 'cheffish/chef_provider_base'
2
- require 'chef/resource/chef_group'
3
- require 'chef/chef_fs/data_handler/group_data_handler'
4
-
5
- class Chef::Provider::ChefGroup < Cheffish::ChefProviderBase
6
-
7
- def whyrun_supported?
8
- true
9
- end
10
-
11
- action :create do
12
- differences = json_differences(current_json, new_json)
13
-
14
- if current_resource_exists?
15
- if differences.size > 0
16
- description = [ "update group #{new_resource.name} at #{rest.url}" ] + differences
17
- converge_by description do
18
- rest.put("groups/#{new_resource.name}", normalize_for_put(new_json))
19
- end
20
- end
21
- else
22
- description = [ "create group #{new_resource.name} at #{rest.url}" ] + differences
23
- converge_by description do
24
- rest.post("groups", normalize_for_post(new_json))
25
- end
26
- end
27
- end
28
-
29
- action :delete do
30
- if current_resource_exists?
31
- converge_by "delete group #{new_resource.name} at #{rest.url}" do
32
- rest.delete("groups/#{new_resource.name}")
33
- end
34
- end
35
- end
36
-
37
- def load_current_resource
38
- begin
39
- @current_resource = json_to_resource(rest.get("groups/#{new_resource.name}"))
40
- rescue Net::HTTPServerException => e
41
- if e.response.code == "404"
42
- @current_resource = not_found_resource
43
- else
44
- raise
45
- end
46
- end
47
- end
48
-
49
- def augment_new_json(json)
50
- # Apply modifiers
51
- json['users'] |= new_resource.users
52
- json['clients'] |= new_resource.clients
53
- json['groups'] |= new_resource.groups
54
- json['users'] -= new_resource.remove_users
55
- json['clients'] -= new_resource.remove_clients
56
- json['groups'] -= new_resource.remove_groups
57
- json
58
- end
59
-
60
- #
61
- # Helpers
62
- #
63
-
64
- def resource_class
65
- Chef::Resource::ChefGroup
66
- end
67
-
68
- def data_handler
69
- Chef::ChefFS::DataHandler::GroupDataHandler.new
70
- end
71
-
72
- def keys
73
- {
74
- 'name' => :name,
75
- 'groupname' => :name
76
- }
77
- end
78
- end
1
+ require 'cheffish/chef_provider_base'
2
+ require 'chef/resource/chef_group'
3
+ require 'chef/chef_fs/data_handler/group_data_handler'
4
+
5
+ class Chef
6
+ class Provider
7
+ class ChefGroup < Cheffish::ChefProviderBase
8
+ provides :chef_group
9
+
10
+ def whyrun_supported?
11
+ true
12
+ end
13
+
14
+ action :create do
15
+ differences = json_differences(current_json, new_json)
16
+
17
+ if current_resource_exists?
18
+ if differences.size > 0
19
+ description = [ "update group #{new_resource.name} at #{rest.url}" ] + differences
20
+ converge_by description do
21
+ rest.put("groups/#{new_resource.name}", normalize_for_put(new_json))
22
+ end
23
+ end
24
+ else
25
+ description = [ "create group #{new_resource.name} at #{rest.url}" ] + differences
26
+ converge_by description do
27
+ rest.post("groups", normalize_for_post(new_json))
28
+ end
29
+ end
30
+ end
31
+
32
+ action :delete do
33
+ if current_resource_exists?
34
+ converge_by "delete group #{new_resource.name} at #{rest.url}" do
35
+ rest.delete("groups/#{new_resource.name}")
36
+ end
37
+ end
38
+ end
39
+
40
+ def load_current_resource
41
+ begin
42
+ @current_resource = json_to_resource(rest.get("groups/#{new_resource.name}"))
43
+ rescue Net::HTTPServerException => e
44
+ if e.response.code == "404"
45
+ @current_resource = not_found_resource
46
+ else
47
+ raise
48
+ end
49
+ end
50
+ end
51
+
52
+ def augment_new_json(json)
53
+ # Apply modifiers
54
+ json['users'] |= new_resource.users
55
+ json['clients'] |= new_resource.clients
56
+ json['groups'] |= new_resource.groups
57
+ json['users'] -= new_resource.remove_users
58
+ json['clients'] -= new_resource.remove_clients
59
+ json['groups'] -= new_resource.remove_groups
60
+ json
61
+ end
62
+
63
+ #
64
+ # Helpers
65
+ #
66
+
67
+ def resource_class
68
+ Chef::Resource::ChefGroup
69
+ end
70
+
71
+ def data_handler
72
+ Chef::ChefFS::DataHandler::GroupDataHandler.new
73
+ end
74
+
75
+ def keys
76
+ {
77
+ 'name' => :name,
78
+ 'groupname' => :name
79
+ }
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,164 +1,169 @@
1
- require 'chef/provider/lwrp_base'
2
- require 'chef/chef_fs/file_pattern'
3
- require 'chef/chef_fs/file_system'
4
- require 'chef/chef_fs/parallelizer'
5
- require 'chef/chef_fs/file_system/chef_server_root_dir'
6
- require 'chef/chef_fs/file_system/chef_repository_file_system_root_dir'
7
-
8
- class Chef::Provider::ChefMirror < Chef::Provider::LWRPBase
9
-
10
- def whyrun_supported?
11
- true
12
- end
13
-
14
- action :upload do
15
- with_modified_config do
16
- copy_to(local_fs, remote_fs)
17
- end
18
- end
19
-
20
- action :download do
21
- with_modified_config do
22
- copy_to(remote_fs, local_fs)
23
- end
24
- end
25
-
26
- def with_modified_config
27
- # pre-Chef-12 ChefFS reads versioned_cookbooks out of Chef::Config instead of
28
- # taking it as an input, so we need to modify it for the duration of copy_to
29
- @old_versioned_cookbooks = Chef::Config.versioned_cookbooks
30
- # If versioned_cookbooks is explicitly set, set it.
31
- if !new_resource.versioned_cookbooks.nil?
32
- Chef::Config.versioned_cookbooks = new_resource.versioned_cookbooks
33
-
34
- # If new_resource.chef_repo_path is set, versioned_cookbooks defaults to true.
35
- # Otherwise, it stays at its current Chef::Config value.
36
- elsif new_resource.chef_repo_path
37
- Chef::Config.versioned_cookbooks = true
38
- end
39
-
40
- begin
41
- yield
42
- ensure
43
- Chef::Config.versioned_cookbooks = @old_versioned_cookbooks
44
- end
45
- end
46
-
47
- def copy_to(src_root, dest_root)
48
- if new_resource.concurrency && new_resource.concurrency <= 0
49
- raise "chef_mirror.concurrency must be above 0! Was set to #{new_resource.concurrency}"
50
- end
51
- # Honor concurrency
52
- Chef::ChefFS::Parallelizer.threads = (new_resource.concurrency || 10) - 1
53
-
54
- # We don't let the user pass absolute paths; we want to reserve those for
55
- # multi-org support (/organizations/foo).
56
- if new_resource.path[0] == '/'
57
- raise "Absolute paths in chef_mirror not yet supported."
58
- end
59
- # Copy!
60
- path = Chef::ChefFS::FilePattern.new("/#{new_resource.path}")
61
- ui = CopyListener.new(self)
62
- error = Chef::ChefFS::FileSystem.copy_to(path, src_root, dest_root, nil, options, ui, proc { |p| p.path })
63
-
64
- if error
65
- raise "Errors while copying:#{ui.errors.map { |e| "#{e}\n" }.join('')}"
66
- end
67
- end
68
-
69
- def local_fs
70
- # If chef_repo_path is set to a string, put it in the form it usually is in
71
- # chef config (:chef_repo_path, :node_path, etc.)
72
- path_config = new_resource.chef_repo_path
73
- if path_config.is_a?(Hash)
74
- chef_repo_path = path_config.delete(:chef_repo_path)
75
- elsif path_config
76
- chef_repo_path = path_config
77
- path_config = {}
78
- else
79
- chef_repo_path = Chef::Config.chef_repo_path
80
- path_config = Chef::Config
81
- end
82
- chef_repo_path = Array(chef_repo_path).flatten
83
-
84
- # Go through the expected object paths and figure out the local paths for each.
85
- case repo_mode
86
- when 'hosted_everything'
87
- object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles)
88
- else
89
- object_names = %w(clients cookbooks data_bags environments nodes roles users)
90
- end
91
-
92
- object_paths = {}
93
- object_names.each do |object_name|
94
- variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
95
- if path_config[variable_name.to_sym]
96
- paths = Array(path_config[variable_name.to_sym]).flatten
97
- else
98
- paths = chef_repo_path.map { |path| ::File.join(path, object_name) }
99
- end
100
- object_paths[object_name] = paths.map { |path| ::File.expand_path(path) }
101
- end
102
-
103
- # Set up the root dir
104
- Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir.new(object_paths)
105
- end
106
-
107
- def remote_fs
108
- config = {
109
- :chef_server_url => new_resource.chef_server[:chef_server_url],
110
- :node_name => new_resource.chef_server[:options][:client_name],
111
- :client_key => new_resource.chef_server[:options][:signing_key_filename],
112
- :repo_mode => repo_mode,
113
- :versioned_cookbooks => Chef::Config.versioned_cookbooks
114
- }
115
- Chef::ChefFS::FileSystem::ChefServerRootDir.new("remote", config)
116
- end
117
-
118
- def repo_mode
119
- new_resource.chef_server[:chef_server_url] =~ /\/organizations\// ? 'hosted_everything' : 'everything'
120
- end
121
-
122
- def options
123
- result = {
124
- :purge => new_resource.purge,
125
- :freeze => new_resource.freeze,
126
- :diff => new_resource.no_diff,
127
- :dry_run => whyrun_mode?
128
- }
129
- result[:diff] = !result[:diff]
130
- result[:repo_mode] = repo_mode
131
- result[:concurrency] = new_resource.concurrency if new_resource.concurrency
132
- result
133
- end
134
-
135
- def load_current_resource
136
- end
137
-
138
- class CopyListener
139
- def initialize(mirror)
140
- @mirror = mirror
141
- @errors = []
142
- end
143
-
144
- attr_reader :mirror
145
- attr_reader :errors
146
-
147
- # TODO output is not *always* indicative of a change. We may want to give
148
- # ChefFS the ability to tell us that info. For now though, assuming any output
149
- # means change is pretty damn close to the truth.
150
- def output(str)
151
- mirror.converge_by str do
152
- end
153
- end
154
- def warn(str)
155
- mirror.converge_by "WARNING: #{str}" do
156
- end
157
- end
158
- def error(str)
159
- mirror.converge_by "ERROR: #{str}" do
160
- end
161
- @errors << str
162
- end
163
- end
164
- end
1
+ require 'chef/provider/lwrp_base'
2
+ require 'chef/chef_fs/file_pattern'
3
+ require 'chef/chef_fs/file_system'
4
+ require 'chef/chef_fs/parallelizer'
5
+ require 'chef/chef_fs/file_system/chef_server_root_dir'
6
+ require 'chef/chef_fs/file_system/chef_repository_file_system_root_dir'
7
+
8
+ class Chef
9
+ class Provider
10
+ class ChefMirror < Chef::Provider::LWRPBase
11
+ provides :chef_mirror
12
+
13
+ def whyrun_supported?
14
+ true
15
+ end
16
+
17
+ action :upload do
18
+ with_modified_config do
19
+ copy_to(local_fs, remote_fs)
20
+ end
21
+ end
22
+
23
+ action :download do
24
+ with_modified_config do
25
+ copy_to(remote_fs, local_fs)
26
+ end
27
+ end
28
+
29
+ def with_modified_config
30
+ # pre-Chef-12 ChefFS reads versioned_cookbooks out of Chef::Config instead of
31
+ # taking it as an input, so we need to modify it for the duration of copy_to
32
+ @old_versioned_cookbooks = Chef::Config.versioned_cookbooks
33
+ # If versioned_cookbooks is explicitly set, set it.
34
+ if !new_resource.versioned_cookbooks.nil?
35
+ Chef::Config.versioned_cookbooks = new_resource.versioned_cookbooks
36
+
37
+ # If new_resource.chef_repo_path is set, versioned_cookbooks defaults to true.
38
+ # Otherwise, it stays at its current Chef::Config value.
39
+ elsif new_resource.chef_repo_path
40
+ Chef::Config.versioned_cookbooks = true
41
+ end
42
+
43
+ begin
44
+ yield
45
+ ensure
46
+ Chef::Config.versioned_cookbooks = @old_versioned_cookbooks
47
+ end
48
+ end
49
+
50
+ def copy_to(src_root, dest_root)
51
+ if new_resource.concurrency && new_resource.concurrency <= 0
52
+ raise "chef_mirror.concurrency must be above 0! Was set to #{new_resource.concurrency}"
53
+ end
54
+ # Honor concurrency
55
+ Chef::ChefFS::Parallelizer.threads = (new_resource.concurrency || 10) - 1
56
+
57
+ # We don't let the user pass absolute paths; we want to reserve those for
58
+ # multi-org support (/organizations/foo).
59
+ if new_resource.path[0] == '/'
60
+ raise "Absolute paths in chef_mirror not yet supported."
61
+ end
62
+ # Copy!
63
+ path = Chef::ChefFS::FilePattern.new("/#{new_resource.path}")
64
+ ui = CopyListener.new(self)
65
+ error = Chef::ChefFS::FileSystem.copy_to(path, src_root, dest_root, nil, options, ui, proc { |p| p.path })
66
+
67
+ if error
68
+ raise "Errors while copying:#{ui.errors.map { |e| "#{e}\n" }.join('')}"
69
+ end
70
+ end
71
+
72
+ def local_fs
73
+ # If chef_repo_path is set to a string, put it in the form it usually is in
74
+ # chef config (:chef_repo_path, :node_path, etc.)
75
+ path_config = new_resource.chef_repo_path
76
+ if path_config.is_a?(Hash)
77
+ chef_repo_path = path_config.delete(:chef_repo_path)
78
+ elsif path_config
79
+ chef_repo_path = path_config
80
+ path_config = {}
81
+ else
82
+ chef_repo_path = Chef::Config.chef_repo_path
83
+ path_config = Chef::Config
84
+ end
85
+ chef_repo_path = Array(chef_repo_path).flatten
86
+
87
+ # Go through the expected object paths and figure out the local paths for each.
88
+ case repo_mode
89
+ when 'hosted_everything'
90
+ object_names = %w(acls clients cookbooks containers data_bags environments groups nodes roles)
91
+ else
92
+ object_names = %w(clients cookbooks data_bags environments nodes roles users)
93
+ end
94
+
95
+ object_paths = {}
96
+ object_names.each do |object_name|
97
+ variable_name = "#{object_name[0..-2]}_path" # cookbooks -> cookbook_path
98
+ if path_config[variable_name.to_sym]
99
+ paths = Array(path_config[variable_name.to_sym]).flatten
100
+ else
101
+ paths = chef_repo_path.map { |path| ::File.join(path, object_name) }
102
+ end
103
+ object_paths[object_name] = paths.map { |path| ::File.expand_path(path) }
104
+ end
105
+
106
+ # Set up the root dir
107
+ Chef::ChefFS::FileSystem::ChefRepositoryFileSystemRootDir.new(object_paths)
108
+ end
109
+
110
+ def remote_fs
111
+ config = {
112
+ :chef_server_url => new_resource.chef_server[:chef_server_url],
113
+ :node_name => new_resource.chef_server[:options][:client_name],
114
+ :client_key => new_resource.chef_server[:options][:signing_key_filename],
115
+ :repo_mode => repo_mode,
116
+ :versioned_cookbooks => Chef::Config.versioned_cookbooks
117
+ }
118
+ Chef::ChefFS::FileSystem::ChefServerRootDir.new("remote", config)
119
+ end
120
+
121
+ def repo_mode
122
+ new_resource.chef_server[:chef_server_url] =~ /\/organizations\// ? 'hosted_everything' : 'everything'
123
+ end
124
+
125
+ def options
126
+ result = {
127
+ :purge => new_resource.purge,
128
+ :freeze => new_resource.freeze,
129
+ :diff => new_resource.no_diff,
130
+ :dry_run => whyrun_mode?
131
+ }
132
+ result[:diff] = !result[:diff]
133
+ result[:repo_mode] = repo_mode
134
+ result[:concurrency] = new_resource.concurrency if new_resource.concurrency
135
+ result
136
+ end
137
+
138
+ def load_current_resource
139
+ end
140
+
141
+ class CopyListener
142
+ def initialize(mirror)
143
+ @mirror = mirror
144
+ @errors = []
145
+ end
146
+
147
+ attr_reader :mirror
148
+ attr_reader :errors
149
+
150
+ # TODO output is not *always* indicative of a change. We may want to give
151
+ # ChefFS the ability to tell us that info. For now though, assuming any output
152
+ # means change is pretty damn close to the truth.
153
+ def output(str)
154
+ mirror.converge_by str do
155
+ end
156
+ end
157
+ def warn(str)
158
+ mirror.converge_by "WARNING: #{str}" do
159
+ end
160
+ end
161
+ def error(str)
162
+ mirror.converge_by "ERROR: #{str}" do
163
+ end
164
+ @errors << str
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end