Module: ChefZero::ChefData::AclPath

Defined in:
lib/chef_zero/chef_data/acl_path.rb

Overview

Manages translations between REST and ACL data paths and parent paths.

Suggestions

  • make /organizations/ORG/_acl and deprecate organization/_acl and organizations/_acl

  • add endpoints for /containers/(users|organizations|containers)(/_acl)

  • add PUT for */_acl

  • add endpoints for /organizations/ORG/data/containers and /organizations/ORG/cookbooks/containers

  • sane, fully documented ACL model

  • sane inheritance / override model: if actors or groups are explicitly specified on X, they are not inherited from X’s parent

  • stop adding pivotal to acls (he already has access to what he needs)

Constant Summary collapse

ORG_DATA_TYPES =
%w{clients cookbook_artifacts cookbooks containers data environments groups
nodes policies policy_groups roles sandboxes}.freeze
TOP_DATA_TYPES =
%w{containers organizations users}.freeze

Class Method Summary collapse

Class Method Details

.get_acl_data_path(path) ⇒ Object

This method takes a Chef REST path and returns the chef-zero path used to look up the ACL. If an object does not have an ACL directly, it will return nil. Paths like /organizations/ORG/data/bag/item will return nil, because it is the parent path (data/bag) that has an ACL.



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/chef_zero/chef_data/acl_path.rb', line 43

def self.get_acl_data_path(path)
  # Things under organizations have their own acls hierarchy
  if path[0] == "organizations" && path.size >= 2
    under_org = partition_acl_data_path(path[2..-1], ORG_DATA_TYPES)
    if under_org
      path[0..1] + under_org
    end
  else
    partition_acl_data_path(path, TOP_DATA_TYPES)
  end
end

.get_object_path(acl_data_path) ⇒ Object

Reverse transform from acl_data_path to path. /acls/root -> / /acls/** -> /** /organizations/ORG/acls/root -> /organizations/ORG /organizations/ORG/acls/** -> /organizations/ORG/**

This means that /acls/containers/nodes maps to /containers/nodes, not /nodes.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chef_zero/chef_data/acl_path.rb', line 65

def self.get_object_path(acl_data_path)
  if acl_data_path[0] == "acls"
    if acl_data_path[1] == "root"
      []
    else
      acl_data_path[1..-1]
    end
  elsif acl_data_path[0] == "organizations" && acl_data_path[2] == "acls"
    if acl_data_path[3] == "root"
      acl_data_path[0..1]
    else
      acl_data_path[0..1] + acl_data_path[3..-1]
    end
  end
end

.parent_acl_data_path(acl_data_path) ⇒ Object

Method assumes acl_data_path is valid. /organizations/BLAH’s parent is /organizations

An example traversal up the whole tree: /organizations/foo/acls/nodes/mario -> /organizations/foo/acls/containers/nodes -> /organizations/foo/acls/containers/containers -> /organizations/foo/acls/root -> /acls/containers/organizations -> /acls/containers/containers -> /acls/root -> nil



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/chef_zero/chef_data/acl_path.rb', line 93

def self.parent_acl_data_path(acl_data_path)
  if acl_data_path[0] == "organizations"
    under_org = partition_parent_acl_data_path(acl_data_path[2..-1])
    if under_org
      acl_data_path[0..1] + under_org
    else
      # ACL data path is /organizations/X/acls/root; therefore parent is "/organizations"
      %w{acls containers organizations}
    end
  else
    partition_parent_acl_data_path(acl_data_path)
  end
end

.partition_acl_data_path(path, data_types) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/chef_zero/chef_data/acl_path.rb', line 127

def self.partition_acl_data_path(path, data_types)
  if path.size == 0
    %w{acls root}
  elsif data_types.include?(path[0])
    if path.size == 0
      [ "acls", "containers", path[0] ]
    elsif path.size == 2
      [ "acls", path[0], path[1] ]
    end
  end
end

.partition_parent_acl_data_path(acl_data_path) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
# File 'lib/chef_zero/chef_data/acl_path.rb', line 114

def self.partition_parent_acl_data_path(acl_data_path)
  if acl_data_path.size == 3
    if acl_data_path == %w{acls containers containers}
      %w{acls root}
    else
      [ "acls", "containers", acl_data_path[1]]
    end
  else
    nil
  end
end