chef 12.0.0.alpha.1 → 12.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application.rb +8 -1
  3. data/lib/chef/application/apply.rb +4 -0
  4. data/lib/chef/application/client.rb +7 -7
  5. data/lib/chef/application/solo.rb +21 -13
  6. data/lib/chef/chef_fs/chef_fs_data_store.rb +60 -6
  7. data/lib/chef/chef_fs/config.rb +78 -4
  8. data/lib/chef/chef_fs/data_handler/acl_data_handler.rb +2 -2
  9. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +1 -1
  10. data/lib/chef/chef_fs/data_handler/container_data_handler.rb +1 -1
  11. data/lib/chef/chef_fs/data_handler/cookbook_data_handler.rb +1 -1
  12. data/lib/chef/chef_fs/data_handler/data_bag_item_data_handler.rb +1 -1
  13. data/lib/chef/chef_fs/data_handler/data_handler_base.rb +76 -2
  14. data/lib/chef/chef_fs/data_handler/environment_data_handler.rb +1 -1
  15. data/lib/chef/chef_fs/data_handler/group_data_handler.rb +1 -1
  16. data/lib/chef/chef_fs/data_handler/node_data_handler.rb +1 -1
  17. data/lib/chef/chef_fs/data_handler/organization_data_handler.rb +30 -0
  18. data/lib/chef/chef_fs/data_handler/organization_invites_data_handler.rb +17 -0
  19. data/lib/chef/chef_fs/data_handler/organization_members_data_handler.rb +17 -0
  20. data/lib/chef/chef_fs/data_handler/role_data_handler.rb +1 -1
  21. data/lib/chef/chef_fs/data_handler/user_data_handler.rb +2 -1
  22. data/lib/chef/chef_fs/file_system.rb +0 -1
  23. data/lib/chef/chef_fs/file_system/acl_entry.rb +1 -1
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +1 -1
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +5 -1
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +73 -13
  27. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +44 -5
  28. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +1 -1
  29. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -3
  30. data/lib/chef/chef_fs/file_system/org_entry.rb +34 -0
  31. data/lib/chef/chef_fs/file_system/organization_invites_entry.rb +58 -0
  32. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +57 -0
  33. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +13 -4
  34. data/lib/chef/chef_fs/knife.rb +1 -1
  35. data/lib/chef/client.rb +8 -2
  36. data/lib/chef/config.rb +75 -57
  37. data/lib/chef/config_fetcher.rb +6 -21
  38. data/lib/chef/dsl/data_query.rb +48 -3
  39. data/lib/chef/dsl/platform_introspection.rb +42 -0
  40. data/lib/chef/dsl/reboot_pending.rb +6 -3
  41. data/lib/chef/encrypted_data_bag_item.rb +1 -1
  42. data/lib/chef/encrypted_data_bag_item/encryptor.rb +12 -0
  43. data/lib/chef/exceptions.rb +2 -0
  44. data/lib/chef/http/basic_client.rb +14 -0
  45. data/lib/chef/http/json_output.rb +7 -2
  46. data/lib/chef/knife.rb +36 -121
  47. data/lib/chef/knife/bootstrap.rb +68 -54
  48. data/lib/chef/knife/bootstrap/archlinux-gems.erb +6 -1
  49. data/lib/chef/knife/bootstrap/chef-aix.erb +5 -0
  50. data/lib/chef/knife/bootstrap/chef-full.erb +5 -1
  51. data/lib/chef/knife/core/bootstrap_context.rb +70 -29
  52. data/lib/chef/knife/search.rb +56 -12
  53. data/lib/chef/knife/serve.rb +1 -1
  54. data/lib/chef/local_mode.rb +10 -4
  55. data/lib/chef/mixin/deep_merge.rb +6 -3
  56. data/lib/chef/mixin/shell_out.rb +33 -17
  57. data/lib/chef/null_logger.rb +72 -0
  58. data/lib/chef/platform.rb +2 -1
  59. data/lib/chef/platform/provider_mapping.rb +1 -1
  60. data/lib/chef/platform/rebooter.rb +54 -0
  61. data/lib/chef/provider/ifconfig.rb +15 -16
  62. data/lib/chef/provider/link.rb +1 -1
  63. data/lib/chef/provider/mount/mount.rb +1 -1
  64. data/lib/chef/provider/mount/solaris.rb +102 -64
  65. data/lib/chef/provider/package/aix.rb +4 -12
  66. data/lib/chef/provider/package/ips.rb +8 -12
  67. data/lib/chef/provider/package/macports.rb +4 -12
  68. data/lib/chef/provider/package/pacman.rb +2 -6
  69. data/lib/chef/provider/package/portage.rb +2 -6
  70. data/lib/chef/provider/package/rpm.rb +4 -12
  71. data/lib/chef/provider/package/solaris.rb +4 -12
  72. data/lib/chef/provider/reboot.rb +69 -0
  73. data/lib/chef/provider/service/debian.rb +10 -10
  74. data/lib/chef/provider/service/freebsd.rb +89 -73
  75. data/lib/chef/provider/service/gentoo.rb +2 -2
  76. data/lib/chef/provider/service/init.rb +6 -4
  77. data/lib/chef/provider/service/insserv.rb +3 -3
  78. data/lib/chef/provider/service/macosx.rb +2 -2
  79. data/lib/chef/provider/service/simple.rb +6 -4
  80. data/lib/chef/provider/service/solaris.rb +1 -1
  81. data/lib/chef/provider/service/systemd.rb +9 -9
  82. data/lib/chef/provider/service/upstart.rb +6 -6
  83. data/lib/chef/provider/subversion.rb +6 -6
  84. data/lib/chef/provider/user/dscl.rb +32 -28
  85. data/lib/chef/provider/user/windows.rb +6 -6
  86. data/lib/chef/provider/whyrun_safe_ruby_block.rb +1 -1
  87. data/lib/chef/providers.rb +1 -0
  88. data/lib/chef/recipe.rb +0 -1
  89. data/lib/chef/resource.rb +3 -5
  90. data/lib/chef/resource/mount.rb +9 -0
  91. data/lib/chef/resource/reboot.rb +48 -0
  92. data/lib/chef/resources.rb +1 -0
  93. data/lib/chef/run_context.rb +25 -0
  94. data/lib/chef/search/query.rb +122 -14
  95. data/lib/chef/util/path_helper.rb +54 -6
  96. data/lib/chef/util/windows/net_user.rb +4 -1
  97. data/lib/chef/version.rb +1 -1
  98. data/lib/chef/win32/api/file.rb +1 -5
  99. data/lib/chef/win32/api/net.rb +1 -0
  100. data/lib/chef/workstation_config_loader.rb +177 -0
  101. data/spec/functional/http/simple_spec.rb +57 -1
  102. data/spec/functional/mixin/shell_out_spec.rb +2 -2
  103. data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +51 -0
  104. data/spec/functional/rebooter_spec.rb +105 -0
  105. data/spec/functional/resource/deploy_revision_spec.rb +0 -4
  106. data/spec/functional/resource/file_spec.rb +26 -3
  107. data/spec/functional/resource/group_spec.rb +5 -3
  108. data/spec/functional/resource/link_spec.rb +16 -16
  109. data/spec/functional/resource/reboot_spec.rb +103 -0
  110. data/spec/integration/client/client_spec.rb +4 -8
  111. data/spec/integration/client/ipv6_spec.rb +1 -1
  112. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +3 -2
  113. data/spec/integration/knife/delete_spec.rb +39 -0
  114. data/spec/integration/knife/deps_spec.rb +30 -20
  115. data/spec/integration/knife/download_spec.rb +77 -1
  116. data/spec/integration/knife/list_spec.rb +221 -0
  117. data/spec/integration/knife/raw_spec.rb +1 -1
  118. data/spec/integration/knife/show_spec.rb +2 -2
  119. data/spec/integration/knife/upload_spec.rb +154 -1
  120. data/spec/support/pedant/run_pedant.rb +0 -1
  121. data/spec/support/shared/functional/http.rb +8 -1
  122. data/spec/support/shared/integration/integration_helper.rb +11 -19
  123. data/spec/support/shared/unit/platform_introspector.rb +22 -0
  124. data/spec/unit/application/apply.rb +11 -1
  125. data/spec/unit/application/solo_spec.rb +19 -3
  126. data/spec/unit/chef_fs/config_spec.rb +58 -0
  127. data/spec/unit/config_fetcher_spec.rb +1 -3
  128. data/spec/unit/config_spec.rb +247 -220
  129. data/spec/unit/dsl/data_query_spec.rb +165 -23
  130. data/spec/unit/dsl/reboot_pending_spec.rb +1 -7
  131. data/spec/unit/encrypted_data_bag_item_spec.rb +1 -1
  132. data/spec/unit/knife/bootstrap_spec.rb +354 -182
  133. data/spec/unit/knife/core/bootstrap_context_spec.rb +67 -30
  134. data/spec/unit/knife_spec.rb +3 -30
  135. data/spec/unit/mixin/deep_merge_spec.rb +14 -0
  136. data/spec/unit/mixin/shell_out_spec.rb +134 -64
  137. data/spec/unit/provider/ifconfig/debian_spec.rb +19 -9
  138. data/spec/unit/provider/ifconfig/redhat_spec.rb +16 -14
  139. data/spec/unit/provider/ifconfig_spec.rb +3 -3
  140. data/spec/unit/provider/link_spec.rb +5 -5
  141. data/spec/unit/provider/mount/mount_spec.rb +10 -1
  142. data/spec/unit/provider/mount/solaris_spec.rb +185 -11
  143. data/spec/unit/provider/package/aix_spec.rb +5 -17
  144. data/spec/unit/provider/package/ips_spec.rb +8 -21
  145. data/spec/unit/provider/package/macports_spec.rb +12 -12
  146. data/spec/unit/provider/package/pacman_spec.rb +4 -12
  147. data/spec/unit/provider/package/portage_spec.rb +5 -15
  148. data/spec/unit/provider/package/rpm_spec.rb +7 -22
  149. data/spec/unit/provider/package/solaris_spec.rb +5 -16
  150. data/spec/unit/provider/service/arch_service_spec.rb +8 -14
  151. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  152. data/spec/unit/provider/service/freebsd_service_spec.rb +457 -225
  153. data/spec/unit/provider/service/gentoo_service_spec.rb +2 -2
  154. data/spec/unit/provider/service/init_service_spec.rb +10 -10
  155. data/spec/unit/provider/service/insserv_service_spec.rb +3 -4
  156. data/spec/unit/provider/service/invokercd_service_spec.rb +8 -9
  157. data/spec/unit/provider/service/macosx_spec.rb +5 -5
  158. data/spec/unit/provider/service/simple_service_spec.rb +4 -6
  159. data/spec/unit/provider/service/solaris_smf_service_spec.rb +1 -3
  160. data/spec/unit/provider/service/systemd_service_spec.rb +20 -20
  161. data/spec/unit/provider/service/upstart_service_spec.rb +15 -17
  162. data/spec/unit/provider/subversion_spec.rb +5 -6
  163. data/spec/unit/provider/user/dscl_spec.rb +2 -1
  164. data/spec/unit/provider/user/windows_spec.rb +7 -0
  165. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +2 -2
  166. data/spec/unit/resource/mount_spec.rb +9 -0
  167. data/spec/unit/resource_spec.rb +0 -4
  168. data/spec/unit/rest_spec.rb +1 -1
  169. data/spec/unit/run_context_spec.rb +15 -0
  170. data/spec/unit/search/query_spec.rb +196 -40
  171. data/spec/unit/util/path_helper_spec.rb +111 -28
  172. data/spec/unit/workstation_config_loader_spec.rb +283 -0
  173. metadata +36 -20
  174. data/lib/chef/knife/bootstrap/centos5-gems.erb +0 -62
  175. data/lib/chef/knife/bootstrap/fedora13-gems.erb +0 -44
  176. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +0 -53
  177. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +0 -48
  178. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +0 -46
  179. data/spec/support/shared/integration/chef_zero_support.rb +0 -130
  180. data/spec/unit/knife/config_file_selection_spec.rb +0 -135
@@ -17,7 +17,7 @@ class Chef
17
17
  })
18
18
  end
19
19
 
20
- def preserve_key(key)
20
+ def preserve_key?(key)
21
21
  return key == 'name'
22
22
  end
23
23
 
@@ -36,7 +36,7 @@ class Chef
36
36
  result
37
37
  end
38
38
 
39
- def preserve_key(key)
39
+ def preserve_key?(key)
40
40
  return key == 'name'
41
41
  end
42
42
 
@@ -21,7 +21,7 @@ class Chef
21
21
  result
22
22
  end
23
23
 
24
- def preserve_key(key)
24
+ def preserve_key?(key)
25
25
  return key == 'name'
26
26
  end
27
27
 
@@ -0,0 +1,30 @@
1
+ require 'chef/chef_fs/data_handler/data_handler_base'
2
+
3
+ class Chef
4
+ module ChefFS
5
+ module DataHandler
6
+ class OrganizationDataHandler < DataHandlerBase
7
+ def normalize(organization, entry)
8
+ result = normalize_hash(organization, {
9
+ 'name' => entry.org,
10
+ 'full_name' => entry.org,
11
+ 'org_type' => 'Business',
12
+ 'clientname' => "#{entry.org}-validator",
13
+ 'billing_plan' => 'platform-free',
14
+ })
15
+ result
16
+ end
17
+
18
+ def preserve_key?(key)
19
+ return key == 'name'
20
+ end
21
+
22
+ def verify_integrity(object, entry, &on_error)
23
+ if entry.org != object['name']
24
+ on_error.call("Name must be '#{entry.org}' (is '#{object['name']}')")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require 'chef/chef_fs/data_handler/data_handler_base'
2
+
3
+ class Chef
4
+ module ChefFS
5
+ module DataHandler
6
+ class OrganizationInvitesDataHandler < DataHandlerBase
7
+ def normalize(invites, entry)
8
+ invites.map { |invite| invite.is_a?(Hash) ? invite['username'] : invite }.sort.uniq
9
+ end
10
+
11
+ def minimize(invites, entry)
12
+ invites
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'chef/chef_fs/data_handler/data_handler_base'
2
+
3
+ class Chef
4
+ module ChefFS
5
+ module DataHandler
6
+ class OrganizationMembersDataHandler < DataHandlerBase
7
+ def normalize(members, entry)
8
+ members.map { |member| member.is_a?(Hash) ? member['user']['username'] : member }.sort.uniq
9
+ end
10
+
11
+ def minimize(members, entry)
12
+ members
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -23,7 +23,7 @@ class Chef
23
23
  result
24
24
  end
25
25
 
26
- def preserve_key(key)
26
+ def preserve_key?(key)
27
27
  return key == 'name'
28
28
  end
29
29
 
@@ -7,6 +7,7 @@ class Chef
7
7
  def normalize(user, entry)
8
8
  normalize_hash(user, {
9
9
  'name' => remove_dot_json(entry.name),
10
+ 'username' => remove_dot_json(entry.name),
10
11
  'admin' => false,
11
12
  'json_class' => 'Chef::WebUIUser',
12
13
  'chef_type' => 'webui_user',
@@ -16,7 +17,7 @@ class Chef
16
17
  })
17
18
  end
18
19
 
19
- def preserve_key(key)
20
+ def preserve_key?(key)
20
21
  return key == 'name'
21
22
  end
22
23
 
@@ -273,7 +273,6 @@ class Chef
273
273
  # case we shouldn't waste time trying PUT if we know the file doesn't
274
274
  # exist.
275
275
  # Will need to decide how that works with checksums, though.
276
-
277
276
  error = false
278
277
  begin
279
278
  dest_path = format_path.call(dest_entry) if ui
@@ -32,7 +32,7 @@ class Chef
32
32
  end
33
33
 
34
34
  def delete(recurse)
35
- raise Chef::ChefFS::FileSystem::OperationNotAllowedError.new(:delete, self, e), "ACLs cannot be deleted."
35
+ raise Chef::ChefFS::FileSystem::OperationNotAllowedError.new(:delete, self), "ACLs cannot be deleted."
36
36
  end
37
37
 
38
38
  def write(file_contents)
@@ -35,7 +35,7 @@ class Chef
35
35
  loader = Chef::Cookbook::CookbookVersionLoader.new(file_path, parent.chefignore)
36
36
  # We need the canonical cookbook name if we are using versioned cookbooks, but we don't
37
37
  # want to spend a lot of time adding code to the main Chef libraries
38
- if Chef::Config[:versioned_cookbooks]
38
+ if root.versioned_cookbooks
39
39
  _canonical_name = canonical_cookbook_name(File.basename(file_path))
40
40
  fail "When versioned_cookbooks mode is on, cookbook #{file_path} must match format <cookbook_name>-x.y.z" unless _canonical_name
41
41
 
@@ -31,8 +31,12 @@ class Chef
31
31
  @data_handler = data_handler
32
32
  end
33
33
 
34
+ def write_pretty_json=(value)
35
+ @write_pretty_json = value
36
+ end
37
+
34
38
  def write_pretty_json
35
- root.write_pretty_json
39
+ @write_pretty_json.nil? ? root.write_pretty_json : @write_pretty_json
36
40
  end
37
41
 
38
42
  def data_handler
@@ -33,32 +33,71 @@ require 'chef/chef_fs/data_handler/container_data_handler'
33
33
  class Chef
34
34
  module ChefFS
35
35
  module FileSystem
36
+ #
37
+ # Represents the root of a local Chef repository, with directories for
38
+ # nodes, cookbooks, roles, etc. under it.
39
+ #
36
40
  class ChefRepositoryFileSystemRootDir < BaseFSDir
37
- def initialize(child_paths)
41
+ #
42
+ # Create a new Chef Repository File System root.
43
+ #
44
+ # == Parameters
45
+ # [child_paths]
46
+ # A hash of child paths, e.g.:
47
+ # "nodes" => [ '/var/nodes', '/home/jkeiser/nodes' ],
48
+ # "roles" => [ '/var/roles' ],
49
+ # ...
50
+ # [root_paths]
51
+ # An array of paths representing the top level, where
52
+ # +org.json+, +members.json+, and +invites.json+ will be stored.
53
+ # [chef_config] - a hash of options that looks suspiciously like the ones
54
+ # stored in Chef::Config, containing at least these keys:
55
+ # :versioned_cookbooks:: whether to include versions in cookbook names
56
+ def initialize(child_paths, root_paths=[], chef_config=Chef::Config)
38
57
  super("", nil)
39
58
  @child_paths = child_paths
59
+ @root_paths = root_paths
60
+ @versioned_cookbooks = chef_config[:versioned_cookbooks]
40
61
  end
41
62
 
42
63
  attr_accessor :write_pretty_json
43
64
 
65
+ attr_reader :root_paths
44
66
  attr_reader :child_paths
67
+ attr_reader :versioned_cookbooks
68
+
69
+ CHILDREN = %w(invitations.json members.json org.json)
45
70
 
46
71
  def children
47
- @children ||= child_paths.keys.sort.map { |name| make_child_entry(name) }.select { |child| !child.nil? }
72
+ @children ||= begin
73
+ result = child_paths.keys.sort.map { |name| make_child_entry(name) }.select { |child| !child.nil? }
74
+ result += root_dir.children.select { |c| CHILDREN.include?(c.name) } if root_dir
75
+ result.sort_by { |c| c.name }
76
+ end
48
77
  end
49
78
 
50
79
  def can_have_child?(name, is_dir)
51
- child_paths.has_key?(name) && is_dir
80
+ if is_dir
81
+ child_paths.has_key?(name)
82
+ elsif root_dir
83
+ CHILDREN.include?(name)
84
+ else
85
+ false
86
+ end
52
87
  end
53
88
 
54
89
  def create_child(name, file_contents = nil)
55
- child_paths[name].each do |path|
56
- begin
57
- Dir.mkdir(path)
58
- rescue Errno::EEXIST
90
+ if file_contents
91
+ child = root_dir.create_child(name, file_contents)
92
+ else
93
+ child_paths[name].each do |path|
94
+ begin
95
+ Dir.mkdir(path)
96
+ rescue Errno::EEXIST
97
+ end
59
98
  end
99
+ child = make_child_entry(name)
60
100
  end
61
- child = make_child_entry(name)
62
101
  @children = nil
63
102
  child
64
103
  end
@@ -67,17 +106,17 @@ class Chef
67
106
  nil
68
107
  end
69
108
 
70
- # Used to print out the filesystem
109
+ # Used to print out a human-readable file system description
71
110
  def fs_description
72
- repo_path = File.dirname(child_paths['cookbooks'][0])
73
- result = "repository at #{repo_path}\n"
74
- if Chef::Config[:versioned_cookbooks]
111
+ repo_paths = root_paths || [ File.dirname(child_paths['cookbooks'][0]) ]
112
+ result = "repository at #{repo_paths.join(', ')}\n"
113
+ if versioned_cookbooks
75
114
  result << " Multiple versions per cookbook\n"
76
115
  else
77
116
  result << " One version per cookbook\n"
78
117
  end
79
118
  child_paths.each_pair do |name, paths|
80
- if paths.any? { |path| File.dirname(path) != repo_path }
119
+ if paths.any? { |path| !repo_paths.include?(File.dirname(path)) }
81
120
  result << " #{name} at #{paths.join(', ')}\n"
82
121
  end
83
122
  end
@@ -86,6 +125,27 @@ class Chef
86
125
 
87
126
  private
88
127
 
128
+ #
129
+ # A FileSystemEntry representing the root path where invites.json,
130
+ # members.json and org.json may be found.
131
+ #
132
+ def root_dir
133
+ existing_paths = root_paths.select { |path| File.exists?(path) }
134
+ if existing_paths.size > 0
135
+ MultiplexedDir.new(existing_paths.map do |path|
136
+ dir = ChefRepositoryFileSystemEntry.new(name, parent, path)
137
+ dir.write_pretty_json = !!write_pretty_json
138
+ dir
139
+ end)
140
+ end
141
+ end
142
+
143
+ #
144
+ # Create a child entry of the appropriate type:
145
+ # cookbooks, data_bags, acls, etc. All will be multiplexed (i.e. if
146
+ # you have multiple paths for cookbooks, the multiplexed dir will grab
147
+ # cookbooks from all of them when you list or grab them).
148
+ #
89
149
  def make_child_entry(name)
90
150
  paths = child_paths[name].select do |path|
91
151
  File.exists?(path)
@@ -23,6 +23,9 @@ require 'chef/chef_fs/file_system/rest_list_dir'
23
23
  require 'chef/chef_fs/file_system/cookbooks_dir'
24
24
  require 'chef/chef_fs/file_system/data_bags_dir'
25
25
  require 'chef/chef_fs/file_system/nodes_dir'
26
+ require 'chef/chef_fs/file_system/org_entry'
27
+ require 'chef/chef_fs/file_system/organization_invites_entry'
28
+ require 'chef/chef_fs/file_system/organization_members_entry'
26
29
  require 'chef/chef_fs/file_system/environments_dir'
27
30
  require 'chef/chef_fs/data_handler/client_data_handler'
28
31
  require 'chef/chef_fs/data_handler/role_data_handler'
@@ -33,7 +36,35 @@ require 'chef/chef_fs/data_handler/container_data_handler'
33
36
  class Chef
34
37
  module ChefFS
35
38
  module FileSystem
39
+ #
40
+ # Represents the root of a Chef server (or organization), under which
41
+ # nodes, roles, cookbooks, etc. can be found.
42
+ #
36
43
  class ChefServerRootDir < BaseFSDir
44
+ #
45
+ # Create a new Chef server root.
46
+ #
47
+ # == Parameters
48
+ #
49
+ # [root_name]
50
+ # A friendly name for the root, for printing--like "remote" or "chef_central".
51
+ # [chef_config]
52
+ # A hash with options that look suspiciously like Chef::Config, including the
53
+ # following keys:
54
+ # :chef_server_url:: The URL to the Chef server or top of the organization
55
+ # :node_name:: The username to authenticate to the Chef server with
56
+ # :client_key:: The private key for the user for authentication
57
+ # :environment:: The environment in which you are presently working
58
+ # :repo_mode::
59
+ # The repository mode, :hosted_everything, :everything or :static.
60
+ # This determines the set of subdirectories the Chef server will
61
+ # offer up.
62
+ # :versioned_cookbooks:: whether or not to include versions in cookbook names
63
+ # [options]
64
+ # Other options:
65
+ # :cookbook_version:: when cookbooks are retrieved, grab this version for them.
66
+ # :freeze:: freeze cookbooks on upload
67
+ #
37
68
  def initialize(root_name, chef_config, options = {})
38
69
  super("", nil)
39
70
  @chef_server_url = chef_config[:chef_server_url]
@@ -41,6 +72,7 @@ class Chef
41
72
  @chef_private_key = chef_config[:client_key]
42
73
  @environment = chef_config[:environment]
43
74
  @repo_mode = chef_config[:repo_mode]
75
+ @versioned_cookbooks = chef_config[:versioned_cookbooks]
44
76
  @root_name = root_name
45
77
  @cookbook_version = options[:cookbook_version] # Used in knife diff and download for server cookbook version
46
78
  end
@@ -51,6 +83,7 @@ class Chef
51
83
  attr_reader :environment
52
84
  attr_reader :repo_mode
53
85
  attr_reader :cookbook_version
86
+ attr_reader :versioned_cookbooks
54
87
 
55
88
  def fs_description
56
89
  "Chef server at #{chef_server_url} (user #{chef_username}), repo_mode = #{repo_mode}"
@@ -81,10 +114,13 @@ class Chef
81
114
  end
82
115
 
83
116
  def org
84
- @org ||= if URI.parse(chef_server_url).path =~ /^\/+organizations\/+([^\/]+)$/
85
- $1
86
- else
87
- nil
117
+ @org ||= begin
118
+ path = Pathname.new(URI.parse(chef_server_url).path).cleanpath
119
+ if File.dirname(path) == '/organizations'
120
+ File.basename(path)
121
+ else
122
+ nil
123
+ end
88
124
  end
89
125
  end
90
126
 
@@ -102,7 +138,10 @@ class Chef
102
138
  RestListDir.new("clients", self, nil, Chef::ChefFS::DataHandler::ClientDataHandler.new),
103
139
  RestListDir.new("containers", self, nil, Chef::ChefFS::DataHandler::ContainerDataHandler.new),
104
140
  RestListDir.new("groups", self, nil, Chef::ChefFS::DataHandler::GroupDataHandler.new),
105
- NodesDir.new(self)
141
+ NodesDir.new(self),
142
+ OrgEntry.new("org.json", self),
143
+ OrganizationMembersEntry.new("members.json", self),
144
+ OrganizationInvitesEntry.new("invitations.json", self)
106
145
  ]
107
146
  elsif repo_mode != 'static'
108
147
  result += [
@@ -32,7 +32,7 @@ class Chef
32
32
  @exists = options[:exists]
33
33
  # If the name is apache2-1.0.0 and versioned_cookbooks is on, we know
34
34
  # the actual cookbook_name and version.
35
- if Chef::Config[:versioned_cookbooks]
35
+ if root.versioned_cookbooks
36
36
  if name =~ VALID_VERSIONED_COOKBOOK_NAME
37
37
  @cookbook_name = $1
38
38
  @version = $2
@@ -51,7 +51,7 @@ class Chef
51
51
 
52
52
  def children
53
53
  @children ||= begin
54
- if Chef::Config[:versioned_cookbooks]
54
+ if root.versioned_cookbooks
55
55
  result = []
56
56
  root.get_json("#{api_path}/?num_versions=all").each_pair do |cookbook_name, cookbooks|
57
57
  cookbooks['versions'].each do |cookbook_version|
@@ -71,7 +71,7 @@ class Chef
71
71
  end
72
72
 
73
73
  def upload_cookbook_from(other, options = {})
74
- Chef::Config[:versioned_cookbooks] ? upload_versioned_cookbook(other, options) : upload_unversioned_cookbook(other, options)
74
+ root.versioned_cookbooks ? upload_versioned_cookbook(other, options) : upload_unversioned_cookbook(other, options)
75
75
  rescue Timeout::Error => e
76
76
  raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Timeout writing: #{e}"
77
77
  rescue Net::HTTPServerException => e
@@ -155,7 +155,7 @@ class Chef
155
155
 
156
156
  def can_have_child?(name, is_dir)
157
157
  return false if !is_dir
158
- return false if Chef::Config[:versioned_cookbooks] && name !~ Chef::ChefFS::FileSystem::CookbookDir::VALID_VERSIONED_COOKBOOK_NAME
158
+ return false if root.versioned_cookbooks && name !~ Chef::ChefFS::FileSystem::CookbookDir::VALID_VERSIONED_COOKBOOK_NAME
159
159
  return true
160
160
  end
161
161
  end
@@ -0,0 +1,34 @@
1
+ require 'chef/chef_fs/file_system/rest_list_entry'
2
+ require 'chef/chef_fs/data_handler/organization_data_handler'
3
+
4
+ class Chef
5
+ module ChefFS
6
+ module FileSystem
7
+ # /organizations/NAME/org.json
8
+ # Represents the actual data at /organizations/NAME (the full name, etc.)
9
+ class OrgEntry < RestListEntry
10
+ def initialize(name, parent, exists = nil)
11
+ super(name, parent)
12
+ @exists = exists
13
+ end
14
+
15
+ def data_handler
16
+ Chef::ChefFS::DataHandler::OrganizationDataHandler.new
17
+ end
18
+
19
+ # /organizations/foo/org.json -> GET /organizations/foo
20
+ def api_path
21
+ parent.api_path
22
+ end
23
+
24
+ def exists?
25
+ parent.exists?
26
+ end
27
+
28
+ def delete(recurse)
29
+ raise Chef::ChefFS::FileSystem::OperationNotAllowedError.new(:delete, self)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end