Class: Chef::TidyOrgAcls

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/tidy_acls.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tidy, org) ⇒ TidyOrgAcls

Returns a new instance of TidyOrgAcls.



9
10
11
12
13
14
15
16
17
18
# File 'lib/chef/tidy_acls.rb', line 9

def initialize(tidy, org)
  @tidy = tidy
  @backup_path = @tidy.backup_path
  @org = org
  @clients = []
  @members = []
  @groups = []
  @users = []
  load_actors
end

Instance Attribute Details

#clientsObject

Returns the value of attribute clients.



7
8
9
# File 'lib/chef/tidy_acls.rb', line 7

def clients
  @clients
end

#groupsObject

Returns the value of attribute groups.



7
8
9
# File 'lib/chef/tidy_acls.rb', line 7

def groups
  @groups
end

#membersObject

Returns the value of attribute members.



7
8
9
# File 'lib/chef/tidy_acls.rb', line 7

def members
  @members
end

#usersObject

Returns the value of attribute users.



7
8
9
# File 'lib/chef/tidy_acls.rb', line 7

def users
  @users
end

Instance Method Details

#acl_actors_groups(acl) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/chef/tidy_acls.rb', line 58

def acl_actors_groups(acl)
  actors_seen = []
  groups_seen = []
  acl_ops.each do |op|
    acl[op]['actors'].each do |actor|
      actors_seen.push(actor) unless actors_seen.include?(actor)
    end
    acl[op]['groups'].each do |group|
      groups_seen.push(group) unless groups_seen.include?(group)
    end
  end
  { actors: actors_seen, groups: groups_seen }
end

#acl_opsObject



54
55
56
# File 'lib/chef/tidy_acls.rb', line 54

def acl_ops
  %w( create read update delete grant )
end

#add_actor_to_members(actor) ⇒ Object



117
118
119
120
121
122
# File 'lib/chef/tidy_acls.rb', line 117

def add_actor_to_members(actor)
  @tidy.ui.stdout.puts "REPAIRING: Invalid actor: #{actor} adding to #{@tidy.members_path(@org)}"
  user = { user: { username: actor } }
  @members.push(user)
  @tidy.write_new_file(@members, @tidy.members_path(@org))
end

#add_client_to_org(actor) ⇒ Object



112
113
114
115
# File 'lib/chef/tidy_acls.rb', line 112

def add_client_to_org(actor)
  # TODO
  @tidy.ui.stdout.puts "ACTION NEEDED: Client referenced in acl non-existant: #{actor}"
end

#ambiguous_actor?(actor) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/chef/tidy_acls.rb', line 90

def ambiguous_actor?(actor)
  valid_org_member?(actor) && valid_org_client?(actor)
end

#default_client_acl(client_name) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/chef/tidy_acls.rb', line 193

def default_client_acl(client_name)
  { create: { actors: ['pivotal', "#{@org}-validator", client_name], groups: ['admins'] },
    read: { actors: ['pivotal', "#{@org}-validator", client_name], groups: %w(admins users) },
    update: { actors: ['pivotal', client_name], groups: ['admins'] },
    delete: { actors: ['pivotal', client_name], groups: %w(admins users) },
    grant: { actors: ['pivotal', client_name], groups: ['admins'] } }
end

#default_user_acl(client) ⇒ Object



185
186
187
188
189
190
191
# File 'lib/chef/tidy_acls.rb', line 185

def default_user_acl(client)
  { create: { actors: ['pivotal', client], groups: ['::server-admins'] },
    read: { actors: ['pivotal', client], groups: ['::server-admins', "::#{@org}_read_access_group"] },
    update: { actors: ['pivotal', client], groups: ['::server-admins'] },
    delete: { actors: ['pivotal', client], groups: ['::server-admins'] },
    grant: { actors: ['pivotal', client], groups: ['::server-admins'] } }
end

#ensure_client_read_acls(acl_file) ⇒ Object



154
155
156
157
158
159
160
161
162
163
# File 'lib/chef/tidy_acls.rb', line 154

def ensure_client_read_acls(acl_file)
  acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
  %w(users admins).each do |group|
    unless acl['read']['groups'].include? group
      @tidy.ui.stdout.puts "REPAIRING: Adding read acl for #{group} in #{acl_file}"
      acl['read']['groups'].push(group)
    end
  end
  @tidy.write_new_file(acl, acl_file)
end

#ensure_global_group_acls(acl_file) ⇒ Object

Appends the proper acls for ::server-admins and the org’s read access group if they are missing.



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/chef/tidy_acls.rb', line 139

def ensure_global_group_acls(acl_file)
  acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
  acl_ops.each do |op|
    unless acl[op]['groups'].include? '::server-admins'
      @tidy.ui.stdout.puts "REPAIRING: Adding #{op} acl for ::server-admins in #{acl_file}"
      acl[op]['groups'].push('::server-admins')
    end
    if op == 'read' && !acl[op]['groups'].include?("::#{@org}_read_access_group")
      @tidy.ui.stdout.puts "REPAIRING: Adding #{op} acl for ::#{@org}_read_access_group in #{acl_file}"
      acl[op]['groups'].push("::#{@org}_read_access_group")
    end
  end
  @tidy.write_new_file(acl, acl_file)
end

#fix_ambiguous_actor(actor) ⇒ Object



107
108
109
110
# File 'lib/chef/tidy_acls.rb', line 107

def fix_ambiguous_actor(actor)
  @tidy.ui.stdout.puts "REPAIRING: Ambiguous actor! #{actor} removing from #{@tidy.members_path(@org)}"
  remove_user_from_org(actor)
end

#invalid_group?(actor) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
# File 'lib/chef/tidy_acls.rb', line 84

def invalid_group?(actor)
  @groups.select { |group| group[:name] == actor }.empty? &&
    actor != '::server-admins' &&
    actor != "::#{@org}_read_access_group"
end

#load_actorsObject



46
47
48
49
50
51
52
# File 'lib/chef/tidy_acls.rb', line 46

def load_actors
  load_users
  load_members
  load_clients
  load_groups
  @tidy.ui.stdout.puts "INFO: #{@org} Actors loaded!"
end

#load_clientsObject



32
33
34
35
36
37
# File 'lib/chef/tidy_acls.rb', line 32

def load_clients
  @tidy.ui.stdout.puts "INFO: Loading clients for #{@org}"
  Dir[::File.join(@tidy.clients_path(@org), '*.json')].each do |client|
    @clients.push(FFI_Yajl::Parser.parse(::File.read(client), symbolize_names: true))
  end
end

#load_groupsObject



39
40
41
42
43
44
# File 'lib/chef/tidy_acls.rb', line 39

def load_groups
  @tidy.ui.stdout.puts "INFO: Loading groups for #{@org}"
  Dir[::File.join(@tidy.groups_path(@org), '*.json')].each do |group|
    @groups.push(FFI_Yajl::Parser.parse(::File.read(group), symbolize_names: true))
  end
end

#load_membersObject



27
28
29
30
# File 'lib/chef/tidy_acls.rb', line 27

def load_members
  @tidy.ui.stdout.puts "INFO: Loading members for #{@org}"
  @members = FFI_Yajl::Parser.parse(::File.read(@tidy.members_path(@org)), symbolize_names: true)
end

#load_usersObject



20
21
22
23
24
25
# File 'lib/chef/tidy_acls.rb', line 20

def load_users
  @tidy.ui.stdout.puts 'INFO: Loading users'
  Dir[::File.join(@tidy.users_path, '*.json')].each do |user|
    @users.push(FFI_Yajl::Parser.parse(::File.read(user), symbolize_names: true))
  end
end

#missing_from_members?(actor) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/chef/tidy_acls.rb', line 94

def missing_from_members?(actor)
  valid_global_user?(actor) && !valid_org_member?(actor) && !valid_org_client?(actor)
end

#missing_org_client?(actor) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/chef/tidy_acls.rb', line 98

def missing_org_client?(actor)
  !valid_global_user?(actor) && !valid_org_member?(actor) && !valid_org_client?(actor)
end

#org_aclsObject



102
103
104
105
# File 'lib/chef/tidy_acls.rb', line 102

def org_acls
  @org_acls ||= Dir[::File.join(@tidy.org_acls_path(@org), '**.json')] +
                Dir[::File.join(@tidy.org_acls_path(@org), '**', '*.json')]
end

#remove_group_from_acl(group, acl_file) ⇒ Object



129
130
131
132
133
134
135
136
# File 'lib/chef/tidy_acls.rb', line 129

def remove_group_from_acl(group, acl_file)
  @tidy.ui.stdout.puts "REPAIRING: Removing invalid group: #{group} from #{acl_file}"
  acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
  acl_ops.each do |op|
    acl[op]['groups'].reject! { |the_group| the_group == group }
  end
  @tidy.write_new_file(acl, acl_file)
end

#remove_user_from_org(actor) ⇒ Object



124
125
126
127
# File 'lib/chef/tidy_acls.rb', line 124

def remove_user_from_org(actor)
  @members.reject! { |user| user[:user][:username] == actor }
  @tidy.write_new_file(@members, @tidy.members_path(@org))
end

#valid_global_user?(actor) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/chef/tidy_acls.rb', line 80

def valid_global_user?(actor)
  !@users.select { |user| user[:username] == actor }.empty?
end

#valid_org_client?(actor) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/chef/tidy_acls.rb', line 76

def valid_org_client?(actor)
  !@clients.select { |client| client[:name] == actor }.empty?
end

#valid_org_member?(actor) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/chef/tidy_acls.rb', line 72

def valid_org_member?(actor)
  !@members.select { |user| user[:user][:username] == actor }.empty?
end

#validate_aclsObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/chef/tidy_acls.rb', line 165

def validate_acls
  org_acls.each do |acl_file|
    acl = FFI_Yajl::Parser.parse(::File.read(acl_file), symbolize_names: false)
    actors_groups = acl_actors_groups(acl)
    actors_groups[:actors].each do |actor|
      next if actor == 'pivotal'
      if ambiguous_actor?(actor)
        fix_ambiguous_actor(actor)
      elsif missing_from_members?(actor)
        add_actor_to_members(actor)
      elsif missing_org_client?(actor)
        add_client_to_org(actor)
      end
    end
    actors_groups[:groups].each do |group|
      remove_group_from_acl(group, acl_file) if invalid_group?(group)
    end
  end
end

#validate_client_aclsObject



219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/chef/tidy_acls.rb', line 219

def validate_client_acls
  @clients.each do |client|
    client_acl_path = ::File.join(@tidy.org_acls_path(@org), 'clients', "#{client[:name]}.json")
    begin
      client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
    rescue Errno::ENOENT
      @tidy.ui.stdout.puts "REPAIRING: Replacing missing client acl for #{client[:name]} in #{client_acl_path}."
      @tidy.write_new_file(default_client_acl(client[:name]), client_acl_path, backup = false)
      client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
    end
    ensure_client_read_acls(client_acl_path)
  end
end

#validate_user_aclsObject



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/chef/tidy_acls.rb', line 201

def validate_user_acls
  @members.each do |member|
    user_acl_path = ::File.join(@tidy.user_acls_path, "#{member[:user][:username]}.json")
    begin
      user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
    rescue Errno::ENOENT
      @tidy.ui.stdout.puts "REPAIRING: Replacing missing user acl for #{member[:user][:username]}."
      @tidy.write_new_file(default_user_acl(member), user_acl_path, backup = false)
      user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
    end
    ensure_global_group_acls(user_acl_path)
    actors_groups = acl_actors_groups(user_acl)
    actors_groups[:groups].each do |group|
      remove_group_from_acl(group, user_acl_path) if invalid_group?(group)
    end
  end
end