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)
  puts "REPAIRING: Invalid actor: #{actor} adding to #{@tidy.members_path(@org)}"
  user = { user: { username: actor } }
  @members.push(user)
  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
  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

#ensure_client_read_acls(acl_file) ⇒ Object



161
162
163
164
165
166
167
168
169
170
# File 'lib/chef/tidy_acls.rb', line 161

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
      puts "REPAIRING: Adding read acl for #{group} in #{acl_file}"
      acl['read']['groups'].push(group)
    end
  end
  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.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/chef/tidy_acls.rb', line 146

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'
      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")
      puts "REPAIRING: Adding #{op} acl for ::#{@org}_read_access_group in #{acl_file}"
      acl[op]['groups'].push("::#{@org}_read_access_group")
    end
  end
  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)
  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
  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
  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
  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
  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
  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



136
137
138
139
140
141
142
143
# File 'lib/chef/tidy_acls.rb', line 136

def remove_group_from_acl(group, acl_file)
  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
  write_new_file(acl, acl_file)
end

#remove_user_from_org(actor) ⇒ Object



131
132
133
134
# File 'lib/chef/tidy_acls.rb', line 131

def remove_user_from_org(actor)
  @members.reject! { |user| user[:user][:username] == actor }
  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



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/chef/tidy_acls.rb', line 172

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|
      if invalid_group?(group)
        remove_group_from_acl(group, acl_file)
      end
    end
  end
end

#validate_client_aclsObject



208
209
210
211
212
213
214
# File 'lib/chef/tidy_acls.rb', line 208

def validate_client_acls
  @clients.each do |client|
    client_acl_path = ::File.join(@tidy.org_acls_path(@org), 'clients', "#{client[:name]}.json")
    client_acl = FFI_Yajl::Parser.parse(::File.read(client_acl_path), symbolize_names: false)
    ensure_client_read_acls(client_acl_path)
  end
end

#validate_user_aclsObject



194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/chef/tidy_acls.rb', line 194

def validate_user_acls
  @members.each do |member|
    user_acl_path = ::File.join(@tidy.user_acls_path, "#{member[:user][:username]}.json")
    user_acl = FFI_Yajl::Parser.parse(::File.read(user_acl_path), symbolize_names: false)
    ensure_global_group_acls(user_acl_path)
    actors_groups = acl_actors_groups(user_acl)
    actors_groups[:groups].each do |group|
      if invalid_group?(group)
        remove_group_from_acl(group, user_acl_path)
      end
    end
  end
end

#write_new_file(contents, path) ⇒ Object



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

def write_new_file(contents, path)
  FileUtils.cp(path, "#{path}.orig") unless ::File.exist?("#{path}.orig")
  ::File.open(path, 'w+') do |f|
     f.write(FFI_Yajl::Encoder.encode(contents, pretty: true))
  end
end