chef-zero 2.2.1 → 3.0.0.rc.1

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/Rakefile +5 -1
  4. data/bin/chef-zero +17 -0
  5. data/lib/chef_zero/chef_data/acl_path.rb +139 -0
  6. data/lib/chef_zero/chef_data/cookbook_data.rb +240 -0
  7. data/lib/chef_zero/chef_data/data_normalizer.rb +207 -0
  8. data/lib/chef_zero/chef_data/default_creator.rb +446 -0
  9. data/lib/chef_zero/data_store/default_facade.rb +149 -0
  10. data/lib/chef_zero/data_store/interface_v1.rb +18 -0
  11. data/lib/chef_zero/data_store/memory_store.rb +2 -1
  12. data/lib/chef_zero/data_store/memory_store_v2.rb +3 -36
  13. data/lib/chef_zero/data_store/raw_file_store.rb +147 -0
  14. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +39 -103
  15. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +1 -1
  16. data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -0
  17. data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -0
  18. data/lib/chef_zero/endpoints/actor_endpoint.rb +36 -10
  19. data/lib/chef_zero/endpoints/actors_endpoint.rb +38 -6
  20. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +15 -9
  21. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -0
  22. data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -0
  23. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +1 -1
  24. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +15 -14
  25. data/lib/chef_zero/endpoints/cookbooks_base.rb +2 -2
  26. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +4 -4
  27. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +5 -5
  28. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +5 -4
  29. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +2 -2
  30. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +6 -6
  31. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +2 -2
  32. data/lib/chef_zero/endpoints/environment_endpoint.rb +5 -5
  33. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +2 -2
  34. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +3 -3
  35. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +2 -2
  36. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +1 -1
  37. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -0
  38. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -0
  39. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -0
  40. data/lib/chef_zero/endpoints/node_endpoint.rb +5 -5
  41. data/lib/chef_zero/endpoints/not_found_endpoint.rb +2 -2
  42. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -0
  43. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +29 -0
  44. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -0
  45. data/lib/chef_zero/endpoints/organization_endpoint.rb +41 -0
  46. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +48 -0
  47. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +14 -0
  48. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -0
  49. data/lib/chef_zero/endpoints/organizations_endpoint.rb +55 -0
  50. data/lib/chef_zero/endpoints/principal_endpoint.rb +15 -3
  51. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +8 -6
  52. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +12 -10
  53. data/lib/chef_zero/endpoints/role_endpoint.rb +5 -5
  54. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +2 -2
  55. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +2 -2
  56. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +4 -4
  57. data/lib/chef_zero/endpoints/search_endpoint.rb +10 -10
  58. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -0
  59. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -0
  60. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -0
  61. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -0
  62. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -0
  63. data/lib/chef_zero/rest_base.rb +79 -13
  64. data/lib/chef_zero/rest_error_response.rb +1 -1
  65. data/lib/chef_zero/rest_request.rb +4 -0
  66. data/lib/chef_zero/rest_router.rb +1 -0
  67. data/lib/chef_zero/rspec.rb +55 -8
  68. data/lib/chef_zero/server.rb +87 -21
  69. data/lib/chef_zero/version.rb +1 -1
  70. data/spec/run_oc_pedant.rb +53 -0
  71. data/spec/{run.rb → run_pedant.rb} +13 -4
  72. data/spec/server_spec.rb +54 -0
  73. data/spec/support/oc_pedant.rb +134 -0
  74. data/spec/support/pedant.rb +1 -1
  75. metadata +54 -13
  76. data/lib/chef_zero/cookbook_data.rb +0 -236
  77. data/lib/chef_zero/data_normalizer.rb +0 -146
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_list_endpoint'
3
3
 
4
4
  module ChefZero
@@ -7,13 +7,14 @@ module ChefZero
7
7
  class DataBagsEndpoint < RestListEndpoint
8
8
  def post(request)
9
9
  contents = request.body
10
- name = FFI_Yajl::Parser.parse(contents, :create_additions => false)[identity_key]
10
+ json = JSON.parse(contents, :create_additions => false)
11
+ name = identity_keys.map { |k| json[k] }.select { |v| v }.first
11
12
  if name.nil?
12
- error(400, "Must specify '#{identity_key}' in JSON")
13
+ error(400, "Must specify #{identity_keys.map { |k| k.inspect }.join(' or ')} in JSON")
13
14
  elsif exists_data_dir?(request, request.rest_path[0..1] + ['data', name])
14
15
  error(409, "Object already exists")
15
16
  else
16
- data_store.create_dir(request.rest_path[0..1] + ['data'], name, :recursive)
17
+ create_data_dir(request, request.rest_path[0..1] + ['data'], name, :recursive)
17
18
  json_response(201, {"uri" => "#{build_uri(request.base_uri, request.rest_path + [name])}"})
18
19
  end
19
20
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -7,7 +7,7 @@ module ChefZero
7
7
  class EnvironmentCookbookEndpoint < CookbooksBase
8
8
  def get(request)
9
9
  cookbook_name = request.rest_path[5]
10
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
11
11
  constraints = environment['cookbook_versions'] || {}
12
12
  cookbook_versions = list_data(request, request.rest_path[0..1] + request.rest_path[4..5])
13
13
  if request.query_params['num_versions'] == 'all'
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
  require 'chef_zero/rest_error_response'
4
4
 
@@ -12,7 +12,7 @@ module ChefZero
12
12
 
13
13
  # Get the list of cookbooks and versions desired by the runlist
14
14
  desired_versions = {}
15
- run_list = FFI_Yajl::Parser.parse(request.body, :create_additions => false)['run_list']
15
+ run_list = JSON.parse(request.body, :create_additions => false)['run_list']
16
16
  run_list.each do |run_list_entry|
17
17
  if run_list_entry =~ /(.+)::.+\@(.+)/ || run_list_entry =~ /(.+)\@(.+)/
18
18
  raise RestErrorResponse.new(412, "No such cookbook: #{$1}") if !cookbook_names.include?($1)
@@ -26,7 +26,7 @@ module ChefZero
26
26
  end
27
27
 
28
28
  # Filter by environment constraints
29
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
29
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
30
30
  environment_constraints = environment['cookbook_versions'] || {}
31
31
 
32
32
  desired_versions.each_key do |name|
@@ -48,8 +48,8 @@ module ChefZero
48
48
 
49
49
  result = {}
50
50
  solved.each_pair do |name, versions|
51
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
52
- result[name] = DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, 'MIN')
51
+ cookbook = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
52
+ result[name] = ChefData::DataNormalizer.normalize_cookbook(self, request.rest_path[0..1], cookbook, name, versions[0], request.base_uri, 'MIN')
53
53
  end
54
54
  json_response(200, result)
55
55
  end
@@ -74,7 +74,7 @@ module ChefZero
74
74
  new_unsolved = unsolved[1..-1]
75
75
 
76
76
  # Pick this cookbook, and add dependencies
77
- cookbook_obj = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', solve_for, desired_version]), :create_additions => false)
77
+ cookbook_obj = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', solve_for, desired_version]), :create_additions => false)
78
78
  cookbook_metadata = cookbook_obj['metadata'] || {}
79
79
  cookbook_dependencies = cookbook_metadata['dependencies'] || {}
80
80
  dep_not_found = false
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -6,7 +6,7 @@ module ChefZero
6
6
  # /environments/NAME/cookbooks
7
7
  class EnvironmentCookbooksEndpoint < CookbooksBase
8
8
  def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
9
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
10
  constraints = environment['cookbook_versions'] || {}
11
11
  if request.query_params['num_versions'] == 'all'
12
12
  num_versions = nil
@@ -1,6 +1,6 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_object_endpoint'
3
- require 'chef_zero/data_normalizer'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
4
 
5
5
  module ChefZero
6
6
  module Endpoints
@@ -24,9 +24,9 @@ module ChefZero
24
24
  end
25
25
 
26
26
  def populate_defaults(request, response_json)
27
- response = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
28
- response = DataNormalizer.normalize_environment(response, request.rest_path[3])
29
- FFI_Yajl::Encoder.encode(response, :pretty => true)
27
+ response = JSON.parse(response_json, :create_additions => false)
28
+ response = ChefData::DataNormalizer.normalize_environment(response, request.rest_path[3])
29
+ JSON.pretty_generate(response)
30
30
  end
31
31
  end
32
32
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/rest_base'
3
3
 
4
4
  module ChefZero
@@ -11,7 +11,7 @@ module ChefZero
11
11
 
12
12
  result = {}
13
13
  list_data(request, request.rest_path[0..1] + ['nodes']).each do |name|
14
- node = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['nodes', name]), :create_additions => false)
14
+ node = JSON.parse(get_data(request, request.rest_path[0..1] + ['nodes', name]), :create_additions => false)
15
15
  if node['chef_environment'] == request.rest_path[3]
16
16
  result[name] = build_uri(request.base_uri, request.rest_path[0..1] + ['nodes', name])
17
17
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -6,12 +6,12 @@ module ChefZero
6
6
  # /environment/NAME/recipes
7
7
  class EnvironmentRecipesEndpoint < CookbooksBase
8
8
  def get(request)
9
- environment = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
9
+ environment = JSON.parse(get_data(request, request.rest_path[0..3]), :create_additions => false)
10
10
  constraints = environment['cookbook_versions'] || {}
11
11
  result = []
12
12
  filter_cookbooks(all_cookbooks_list(request), constraints, 1) do |name, versions|
13
13
  if versions.size > 0
14
- cookbook = FFI_Yajl::Parser.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
14
+ cookbook = JSON.parse(get_data(request, request.rest_path[0..1] + ['cookbooks', name, versions[0]]), :create_additions => false)
15
15
  result += recipe_names(name, cookbook)
16
16
  end
17
17
  end
@@ -1,4 +1,4 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/cookbooks_base'
3
3
 
4
4
  module ChefZero
@@ -18,7 +18,7 @@ module ChefZero
18
18
  # Verify that the environment exists
19
19
  get_data(request, environment_path)
20
20
 
21
- role = FFI_Yajl::Parser.parse(get_data(request, role_path), :create_additions => false)
21
+ role = JSON.parse(get_data(request, role_path), :create_additions => false)
22
22
  environment_name = environment_path[3]
23
23
  if environment_name == '_default'
24
24
  run_list = role['run_list']
@@ -14,7 +14,7 @@ module ChefZero
14
14
  end
15
15
 
16
16
  def put(request)
17
- data_store.set(request.rest_path, request.body, :create, :create_dir)
17
+ data_store.set(request.rest_path, request.body, :create, :create_dir, :requestor => request.requestor)
18
18
  json_response(200, {})
19
19
  end
20
20
  end
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require 'chef_zero/endpoints/rest_object_endpoint'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
+
5
+ module ChefZero
6
+ module Endpoints
7
+ # /organizations/ORG/groups/NAME
8
+ class GroupEndpoint < RestObjectEndpoint
9
+ def initialize(server)
10
+ super(server, %w(id groupname))
11
+ end
12
+
13
+ def populate_defaults(request, response_json)
14
+ group = JSON.parse(response_json, :create_additions => false)
15
+ group = ChefData::DataNormalizer.normalize_group(group, request.rest_path[3], request.rest_path[1])
16
+ JSON.pretty_generate(group)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+ require 'chef_zero/endpoints/rest_list_endpoint'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/groups/NAME
7
+ class GroupsEndpoint < RestListEndpoint
8
+ def initialize(server)
9
+ super(server, %w(id groupname))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /license
7
+ class LicenseEndpoint < RestBase
8
+ MAX_NODE_COUNT = 25
9
+
10
+ def get(request)
11
+ node_count = 0
12
+ list_data(request, [ 'organizations' ]).each do |orgname|
13
+ node_count += list_data(request, [ 'organizations', orgname, 'nodes' ]).size
14
+ end
15
+
16
+ json_response(200, {
17
+ "limit_exceeded" => (node_count > MAX_NODE_COUNT) ? true : false,
18
+ "node_license" => MAX_NODE_COUNT,
19
+ "node_count" => node_count,
20
+ "upgrade_url" => 'http://blah.com'
21
+ })
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,15 +1,15 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
  require 'chef_zero/endpoints/rest_object_endpoint'
3
- require 'chef_zero/data_normalizer'
3
+ require 'chef_zero/chef_data/data_normalizer'
4
4
 
5
5
  module ChefZero
6
6
  module Endpoints
7
7
  # /nodes/ID
8
8
  class NodeEndpoint < RestObjectEndpoint
9
9
  def populate_defaults(request, response_json)
10
- node = FFI_Yajl::Parser.parse(response_json, :create_additions => false)
11
- node = DataNormalizer.normalize_node(node, request.rest_path[3])
12
- FFI_Yajl::Encoder.encode(node, :pretty => true)
10
+ node = JSON.parse(response_json, :create_additions => false)
11
+ node = ChefData::DataNormalizer.normalize_node(node, request.rest_path[3])
12
+ JSON.pretty_generate(node)
13
13
  end
14
14
  end
15
15
  end
@@ -1,10 +1,10 @@
1
- require 'ffi_yajl'
1
+ require 'json'
2
2
 
3
3
  module ChefZero
4
4
  module Endpoints
5
5
  class NotFoundEndpoint
6
6
  def call(request)
7
- return [404, {"Content-Type" => "application/json"}, FFI_Yajl::Encoder.encode({"error" => ["Object not found: #{request.env['REQUEST_PATH']}"]}, :pretty => true)]
7
+ return [404, {"Content-Type" => "application/json"}, JSON.pretty_generate({"error" => ["Object not found: #{request.env['REQUEST_PATH']}"]})]
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/association_requests/ID
7
+ class OrganizationAssociationRequestEndpoint < RestBase
8
+ def delete(request)
9
+ orgname = request.rest_path[1]
10
+ id = request.rest_path[3]
11
+ if id !~ /(.+)-#{orgname}$/
12
+ raise HttpErrorResponse.new(404, "Invalid ID #{id}. Must be of the form username-#{orgname}")
13
+ end
14
+ username = $1
15
+ path = request.rest_path[0..-2] + [username]
16
+ data = JSON.parse(get_data(request, path), :create_additions => false)
17
+ delete_data(request, path)
18
+ json_response(200, { "id" => id, "username" => username })
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/association_requests
7
+ class OrganizationAssociationRequestsEndpoint < RestBase
8
+ def post(request)
9
+ json = JSON.parse(request.body, :create_additions => false)
10
+ username = json['user']
11
+ orgname = request.rest_path[1]
12
+ id = "#{username}-#{orgname}"
13
+
14
+ if exists_data?(request, [ 'organizations', orgname, 'users', username ])
15
+ raise RestErrorResponse.new(409, "User #{username} is already in organization #{orgname}")
16
+ end
17
+
18
+ create_data(request, request.rest_path, username, '{}')
19
+ json_response(201, { "uri" => build_uri(request.base_uri, request.rest_path + [ id ]) })
20
+ end
21
+
22
+ def get(request)
23
+ orgname = request.rest_path[1]
24
+ result = list_data(request).map { |username| { "id" => "#{username}-#{orgname}", 'username' => username } }
25
+ json_response(200, result)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/NAME/authenticate_user
7
+ class OrganizationAuthenticateUserEndpoint < RestBase
8
+ def post(request)
9
+ request_json = JSON.parse(request.body, :create_additions => false)
10
+ name = request_json['name']
11
+ password = request_json['password']
12
+ begin
13
+ user = data_store.get(request.rest_path[0..-2] + ['users', name])
14
+ user = JSON.parse(user, :create_additions => false)
15
+ verified = user['password'] == password
16
+ rescue DataStore::DataNotFoundError
17
+ verified = false
18
+ end
19
+ json_response(200, {
20
+ 'name' => name,
21
+ 'verified' => !!verified
22
+ })
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,41 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/NAME
7
+ class OrganizationEndpoint < RestBase
8
+ def get(request)
9
+ org = get_data(request, request.rest_path + [ 'org' ])
10
+ already_json_response(200, populate_defaults(request, org))
11
+ end
12
+
13
+ def put(request)
14
+ org = JSON.parse(get_data(request, request.rest_path + [ 'org' ]), :create_additions => false)
15
+ new_org = JSON.parse(request.body, :create_additions => false)
16
+ new_org.each do |key, value|
17
+ org[key] = value
18
+ end
19
+ org = JSON.pretty_generate(org)
20
+ if new_org['name'] != request.rest_path[-1]
21
+ # This is a rename
22
+ return error(400, "Cannot rename org #{request.rest_path[-1]} to #{new_org['name']}: rename not supported for orgs")
23
+ end
24
+ set_data(request, request.rest_path + [ 'org' ], org)
25
+ json_response(200, "uri" => "#{build_uri(request.base_uri, request.rest_path)}")
26
+ end
27
+
28
+ def delete(request)
29
+ org = get_data(request, request.rest_path + [ 'org' ])
30
+ delete_data_dir(request, request.rest_path)
31
+ already_json_response(200, populate_defaults(request, org))
32
+ end
33
+
34
+ def populate_defaults(request, response_json)
35
+ org = JSON.parse(response_json, :create_additions => false)
36
+ org = ChefData::DataNormalizer.normalize_organization(org, request.rest_path[1])
37
+ JSON.pretty_generate(org)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,48 @@
1
+ require 'json'
2
+ require 'chef_zero/rest_base'
3
+
4
+ module ChefZero
5
+ module Endpoints
6
+ # /organizations/ORG/users/NAME
7
+ class OrganizationUserEndpoint < RestBase
8
+ def get(request)
9
+ username = request.rest_path[3]
10
+ get_data(request) # 404 if user is not in org
11
+ user = get_data(request, [ 'users', username ])
12
+ user = JSON.parse(user, :create_additions => false)
13
+ json_response(200, ChefData::DataNormalizer.normalize_user(user, username, ['username'], server.options[:osc_compat], request.method))
14
+ end
15
+
16
+ def delete(request)
17
+ user = get_data(request)
18
+ delete_data(request)
19
+ user = JSON.parse(user, :create_additions => false)
20
+ json_response(200, ChefData::DataNormalizer.normalize_user(user, request.rest_path[3], ['username'], server.options[:osc_compat]))
21
+ end
22
+
23
+ def post(request)
24
+ orgname = request.rest_path[1]
25
+ username = request.rest_path[3]
26
+
27
+ users = get_data(request, [ 'organizations', orgname, 'groups', 'users' ])
28
+ users = JSON.parse(users, :create_additions => false)
29
+
30
+ create_data(request, [ 'organizations', orgname, 'users' ], username, '{}')
31
+
32
+ # /organizations/ORG/association_requests/USERNAME-ORG
33
+ begin
34
+ delete_data(request, [ 'organizations', orgname, 'association_requests', "#{username}-#{orgname}"], :data_store_exceptions)
35
+ rescue DataStore::DataNotFoundError
36
+ end
37
+
38
+ # Add the user to the users group if it isn't already there
39
+ if !users['users'] || !users['users'].include?(username)
40
+ users['users'] ||= []
41
+ users['users'] |= [ username ]
42
+ set_data(request, [ 'organizations', orgname, 'groups', 'users' ], JSON.pretty_generate(users))
43
+ end
44
+ json_response(200, {})
45
+ end
46
+ end
47
+ end
48
+ end