chef_fixie 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/bin/chef_fixie +1 -1
- data/doc/BulkFixup.md +1 -1
- data/lib/chef_fixie.rb +7 -7
- data/lib/chef_fixie/authz_mapper.rb +26 -28
- data/lib/chef_fixie/authz_objects.rb +44 -41
- data/lib/chef_fixie/bulk_edit_permissions.rb +24 -20
- data/lib/chef_fixie/check_org_associations.rb +40 -39
- data/lib/chef_fixie/config.rb +20 -19
- data/lib/chef_fixie/console.rb +9 -9
- data/lib/chef_fixie/context.rb +2 -4
- data/lib/chef_fixie/sql.rb +12 -12
- data/lib/chef_fixie/sql_objects.rb +44 -37
- data/lib/chef_fixie/utility_helpers.rb +13 -9
- data/lib/chef_fixie/version.rb +1 -1
- data/spec/chef_fixie/acl_spec.rb +23 -25
- data/spec/chef_fixie/assoc_invite_spec.rb +5 -8
- data/spec/chef_fixie/check_org_associations_spec.rb +14 -17
- data/spec/chef_fixie/groups_spec.rb +7 -11
- data/spec/chef_fixie/org_spec.rb +4 -5
- data/spec/chef_fixie/orgs_spec.rb +6 -9
- data/spec/spec_helper.rb +5 -6
- metadata +5 -20
@@ -18,40 +18,44 @@
|
|
18
18
|
# Author: Mark Anderson <mark@chef.io>
|
19
19
|
#
|
20
20
|
|
21
|
-
require_relative
|
22
|
-
require_relative
|
23
|
-
require_relative
|
24
|
-
require_relative
|
21
|
+
require_relative "config"
|
22
|
+
require_relative "authz_objects"
|
23
|
+
require_relative "authz_mapper"
|
24
|
+
require_relative "utility_helpers"
|
25
25
|
|
26
26
|
module ChefFixie
|
27
27
|
module CheckOrgAssociations
|
28
28
|
def self.orgs
|
29
29
|
@orgs ||= ChefFixie::Sql::Orgs.new
|
30
30
|
end
|
31
|
+
|
31
32
|
def self.users
|
32
33
|
@users ||= ChefFixie::Sql::Users.new
|
33
34
|
end
|
35
|
+
|
34
36
|
def self.assocs
|
35
37
|
@assocs ||= ChefFixie::Sql::Associations.new
|
36
38
|
end
|
39
|
+
|
37
40
|
def self.invites
|
38
41
|
invites ||= ChefFixie::Sql::Invites.new
|
39
42
|
end
|
40
43
|
|
41
44
|
def self.make_user(user)
|
42
45
|
if user.is_a?(String)
|
43
|
-
|
46
|
+
users[user]
|
44
47
|
elsif user.is_a?(ChefFixie::Sql::User)
|
45
|
-
|
48
|
+
user
|
46
49
|
else
|
47
50
|
raise "Expected a user, got a #{user.class}"
|
48
51
|
end
|
49
52
|
end
|
53
|
+
|
50
54
|
def self.make_org(org)
|
51
55
|
if org.is_a?(String)
|
52
|
-
|
56
|
+
orgs[org]
|
53
57
|
elsif org.is_a?(ChefFixie::Sql::Org)
|
54
|
-
|
58
|
+
org
|
55
59
|
else
|
56
60
|
raise "Expected an org, got a #{org.class}"
|
57
61
|
end
|
@@ -61,7 +65,6 @@ module ChefFixie
|
|
61
65
|
user = make_user(user)
|
62
66
|
org = make_org(org)
|
63
67
|
org.groups[user.id]
|
64
|
-
|
65
68
|
end
|
66
69
|
|
67
70
|
def self.check_association(org, user, global_admins = nil)
|
@@ -85,7 +88,7 @@ module ChefFixie
|
|
85
88
|
return :user_not_in_usag
|
86
89
|
end
|
87
90
|
|
88
|
-
if !org.groups[
|
91
|
+
if !org.groups["users"].member?(usag)
|
89
92
|
return :usag_not_in_users
|
90
93
|
end
|
91
94
|
|
@@ -96,7 +99,7 @@ module ChefFixie
|
|
96
99
|
if invites.by_org_id_user_id(org.id, user.id)
|
97
100
|
return :zombie_invite
|
98
101
|
end
|
99
|
-
|
102
|
+
true
|
100
103
|
end
|
101
104
|
|
102
105
|
def self.fix_association(org, user, global_admins = nil)
|
@@ -105,7 +108,7 @@ module ChefFixie
|
|
105
108
|
user = users[user] if user.is_a?(String)
|
106
109
|
global_admins ||= org.global_admins
|
107
110
|
|
108
|
-
failure = check_association(org,user,global_admins)
|
111
|
+
failure = check_association(org, user, global_admins)
|
109
112
|
|
110
113
|
case failure
|
111
114
|
when true
|
@@ -115,14 +118,14 @@ module ChefFixie
|
|
115
118
|
usag.group_add(user)
|
116
119
|
when :usag_not_in_users
|
117
120
|
usag = org.groups[user.id]
|
118
|
-
org.groups[
|
121
|
+
org.groups["users"].group_add(usag)
|
119
122
|
when :global_admins_lacks_read
|
120
123
|
user.ace_add(:read, global_admins)
|
121
124
|
else
|
122
125
|
puts "#{org.name} #{user.name} can't fix problem #{failure} yet"
|
123
126
|
return false
|
124
127
|
end
|
125
|
-
|
128
|
+
true
|
126
129
|
end
|
127
130
|
|
128
131
|
def self.check_associations(org)
|
@@ -140,56 +143,54 @@ module ChefFixie
|
|
140
143
|
users_assoc = assocs.by_org_id(org.id).all(:all)
|
141
144
|
users_invite = invites.by_org_id(org.id).all(:all)
|
142
145
|
|
143
|
-
user_ids = users_assoc.map {|a| a.user_id }
|
144
|
-
users_in_org = user_ids.map {|i| users.by_id(i).all.first }
|
145
|
-
usernames = users_in_org.map {|u| u.name }
|
146
|
-
|
146
|
+
user_ids = users_assoc.map { |a| a.user_id }
|
147
|
+
users_in_org = user_ids.map { |i| users.by_id(i).all.first }
|
148
|
+
usernames = users_in_org.map { |u| u.name }
|
147
149
|
|
148
150
|
# check that users aren't both invited and associated
|
149
|
-
invited_ids = users_invite.map {|a| a.user_id }
|
151
|
+
invited_ids = users_invite.map { |a| a.user_id }
|
150
152
|
overlap_ids = user_ids & invited_ids
|
151
153
|
|
152
154
|
if !overlap_ids.empty?
|
153
|
-
overlap_names = overlap_ids.map {|i| users.by_id(i).all.first.name rescue "#{i}" }
|
154
|
-
puts "#{orgname} users both associated and invited: #{overlap_names.join(', ')
|
155
|
+
overlap_names = overlap_ids.map { |i| users.by_id(i).all.first.name rescue "#{i}" }
|
156
|
+
puts "#{orgname} users both associated and invited: #{overlap_names.join(', ')}"
|
155
157
|
success = false
|
156
158
|
end
|
157
159
|
|
158
160
|
# Check that we don't have zombie USAGs left around (not 100% reliable)
|
159
161
|
# because someone could create a group that looks like a USAG
|
160
162
|
possible_usags = org.groups.list(:all) - user_ids
|
161
|
-
usags = possible_usags.select {|n| n =~ /^\h+{20}$/ }
|
163
|
+
usags = possible_usags.select { |n| n =~ /^\h+{20}$/ }
|
162
164
|
if !usags.empty?
|
163
|
-
puts "#{orgname} Suspicious USAGS without associated user #{usags.join(', ')
|
165
|
+
puts "#{orgname} Suspicious USAGS without associated user #{usags.join(', ')}"
|
164
166
|
end
|
165
167
|
|
166
168
|
# Check group membership for sanity
|
167
|
-
success &= check_group(org,
|
168
|
-
success &= check_group(org,
|
169
|
+
success &= check_group(org, "billing-admins", usernames)
|
170
|
+
success &= check_group(org, "admins", usernames)
|
169
171
|
|
170
172
|
# TODO check for non-usags in users!
|
171
|
-
users_members = org.groups[
|
172
|
-
users_actors = users_members[
|
173
|
+
users_members = org.groups["users"].group
|
174
|
+
users_actors = users_members["actors"] - [[:global, "pivotal"]]
|
173
175
|
if !users_actors.empty?
|
174
176
|
puts "#{orgname} has actors in it's users group #{users_actors}"
|
175
177
|
end
|
176
|
-
non_usags = users_members[
|
178
|
+
non_usags = users_members["groups"].map { |g| g[1] } - user_ids
|
177
179
|
if !non_usags.empty?
|
178
180
|
puts "#{orgname} warning: has non usags in it's users group #{non_usags.join(', ')}"
|
179
181
|
end
|
180
182
|
|
181
|
-
|
182
183
|
# Check individual associations
|
183
184
|
users_in_org.each do |user|
|
184
|
-
result =
|
185
|
-
if
|
185
|
+
result = check_association(org, user, global_admins)
|
186
|
+
if result != true
|
186
187
|
puts "Org #{orgname} Association check failed for #{user.name} #{result}"
|
187
188
|
success = false
|
188
189
|
end
|
189
190
|
end
|
190
191
|
|
191
192
|
puts "Org #{orgname} is #{success ? 'ok' : 'bad'} (#{users_in_org.count} users)"
|
192
|
-
|
193
|
+
success
|
193
194
|
end
|
194
195
|
|
195
196
|
# expect at least one current user to be in admins and billing admins
|
@@ -199,21 +200,21 @@ module ChefFixie
|
|
199
200
|
puts "#{orgname} Missing group #{groupname}"
|
200
201
|
return :no_such_group
|
201
202
|
end
|
202
|
-
actors = g.group[
|
203
|
+
actors = g.group["actors"].map { |x| x[1] }
|
203
204
|
live = actors & users
|
204
205
|
|
205
206
|
if live.count == 0
|
206
207
|
puts "Org #{org.name} has no active users in #{groupname}"
|
207
208
|
return false
|
208
209
|
end
|
209
|
-
|
210
|
+
true
|
210
211
|
end
|
211
|
-
|
212
|
+
|
212
213
|
def self.remove_association(org, user)
|
213
214
|
# magic to make usage easier
|
214
215
|
org = make_org(org)
|
215
216
|
user = make_user(user)
|
216
|
-
|
217
|
+
|
217
218
|
# remove USAG
|
218
219
|
usag = org.groups[user.id]
|
219
220
|
usag.delete if usag
|
@@ -222,16 +223,16 @@ module ChefFixie
|
|
222
223
|
org.groups.all(:all).each do |g|
|
223
224
|
g.group_delete(user) if g.member?(user)
|
224
225
|
end
|
225
|
-
|
226
|
+
|
226
227
|
# remove read ACE
|
227
228
|
user.ace_delete(:read, org.global_admins)
|
228
229
|
|
229
230
|
# remove association record
|
230
|
-
assoc = assocs.by_org_id_user_id(org.id,user.id)
|
231
|
+
assoc = assocs.by_org_id_user_id(org.id, user.id)
|
231
232
|
assoc.delete if assoc
|
232
233
|
|
233
234
|
# remove any invites
|
234
|
-
invite = invites.by_org_id_user_id(org.id,user.id)
|
235
|
+
invite = invites.by_org_id_user_id(org.id, user.id)
|
235
236
|
invite.delete if invite
|
236
237
|
end
|
237
238
|
end
|
data/lib/chef_fixie/config.rb
CHANGED
@@ -18,10 +18,10 @@
|
|
18
18
|
#
|
19
19
|
# Much of this code was orginally derived from the orgmapper tool, which had many varied authors.
|
20
20
|
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
21
|
+
require "singleton"
|
22
|
+
require "ffi_yajl"
|
23
|
+
require "pathname"
|
24
|
+
require "veil"
|
25
25
|
|
26
26
|
module ChefFixie
|
27
27
|
def self.configure
|
@@ -66,7 +66,7 @@ module ChefFixie
|
|
66
66
|
KEYS = [:authz_uri, :sql_database, :superuser_id, :pivotal_key]
|
67
67
|
KEYS.each { |k| attr_accessor k }
|
68
68
|
|
69
|
-
def merge_opts(opts={})
|
69
|
+
def merge_opts(opts = {})
|
70
70
|
opts.each do |key, value|
|
71
71
|
send("#{key}=".to_sym, value)
|
72
72
|
end
|
@@ -84,7 +84,7 @@ module ChefFixie
|
|
84
84
|
key_len > max ? key_len : max
|
85
85
|
end
|
86
86
|
KEYS.each do |key|
|
87
|
-
value = send(key) ||
|
87
|
+
value = send(key) || "default"
|
88
88
|
txt << "# %#{max_key_len}s: %s" % [key.to_s, value]
|
89
89
|
end
|
90
90
|
txt.join("\n")
|
@@ -102,25 +102,25 @@ module ChefFixie
|
|
102
102
|
def load_from_pc(dir = "/etc/opscode")
|
103
103
|
configdir = Pathname.new(dir)
|
104
104
|
|
105
|
-
config_files = %w
|
105
|
+
config_files = %w{chef-server-running.json}
|
106
106
|
config = load_json_from_path([configdir], config_files)
|
107
107
|
|
108
|
-
secrets = load_secrets_from_path([configdir], %w
|
108
|
+
secrets = load_secrets_from_path([configdir], %w{private-chef-secrets.json} )
|
109
109
|
|
110
|
-
authz_config = config[
|
111
|
-
authz_vip = authz_config[
|
112
|
-
authz_port = authz_config[
|
110
|
+
authz_config = config["private_chef"]["oc_bifrost"]
|
111
|
+
authz_vip = authz_config["vip"]
|
112
|
+
authz_port = authz_config["port"]
|
113
113
|
@authz_uri = "http://#{authz_vip}:#{authz_port}"
|
114
114
|
|
115
|
-
@superuser_id = dig(secrets,
|
115
|
+
@superuser_id = dig(secrets, %w{oc_bifrost superuser_id}) || authz_config["superuser_id"]
|
116
116
|
|
117
|
-
sql_config = config[
|
118
|
-
erchef_config = config[
|
117
|
+
sql_config = config["private_chef"]["postgresql"]
|
118
|
+
erchef_config = config["private_chef"]["opscode-erchef"]
|
119
119
|
|
120
|
-
sql_user = sql_config[
|
121
|
-
sql_pw = dig(secrets,
|
122
|
-
sql_vip = sql_config[
|
123
|
-
sql_port = sql_config[
|
120
|
+
sql_user = sql_config["sql_user"] || erchef_config["sql_user"]
|
121
|
+
sql_pw = dig(secrets, %w{opscode_erchef sql_password}) || sql_config["sql_password"] || erchef_config["sql_password"]
|
122
|
+
sql_vip = sql_config["vip"]
|
123
|
+
sql_port = sql_config["port"]
|
124
124
|
|
125
125
|
@sql_database = "postgres://#{sql_user}:#{sql_pw}@#{sql_vip}/opscode_chef"
|
126
126
|
|
@@ -139,6 +139,7 @@ module ChefFixie
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
142
|
+
|
142
143
|
def load_secrets_from_path(pathlist, filelist)
|
143
144
|
pathlist.each do |path|
|
144
145
|
filelist.each do |file|
|
@@ -156,7 +157,7 @@ module ChefFixie
|
|
156
157
|
if hash.respond_to?(:get)
|
157
158
|
hash.get(*list)
|
158
159
|
elsif hash.nil?
|
159
|
-
nil
|
160
|
+
nil
|
160
161
|
elsif list.empty?
|
161
162
|
hash
|
162
163
|
else
|
data/lib/chef_fixie/console.rb
CHANGED
@@ -18,12 +18,12 @@
|
|
18
18
|
#
|
19
19
|
# Much of this code was orginally derived from the orgmapper tool, which had many varied authors.
|
20
20
|
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
21
|
+
require "optparse"
|
22
|
+
require "pp"
|
23
|
+
require "pry"
|
24
24
|
|
25
|
-
require_relative
|
26
|
-
require_relative
|
25
|
+
require_relative "../chef_fixie"
|
26
|
+
require_relative "context"
|
27
27
|
|
28
28
|
module ChefFixie
|
29
29
|
module Console
|
@@ -47,9 +47,9 @@ module ChefFixie
|
|
47
47
|
options = {}
|
48
48
|
OptionParser.new do |opt|
|
49
49
|
opt.banner = "Usage: fixie [config] [options]"
|
50
|
-
opt.on(
|
51
|
-
opt.on("--sql_database DATABASE",
|
52
|
-
opt.on_tail(
|
50
|
+
opt.on("--authz_uri AUTH_URI", "The URI of the opscode authz service") { |v| options[:authz_uri] = v }
|
51
|
+
opt.on("--sql_database DATABASE", "The URI of the opscode_chef database") { |v| options[:sql_database] = v }
|
52
|
+
opt.on_tail("-h", "--help", "Show this message") do
|
53
53
|
puts opt
|
54
54
|
puts "\nExample configuration file:\n\n"
|
55
55
|
puts ChefFixie::Config.instance.example_config
|
@@ -68,7 +68,7 @@ module ChefFixie
|
|
68
68
|
Pry.config.history.file = "~/.fixie_history"
|
69
69
|
Pry.config.prompt_name = "fixie"
|
70
70
|
Pry::Commands.block_command("fixie-help", "Show fixie's help") do
|
71
|
-
|
71
|
+
output.puts(<<-HALP)
|
72
72
|
** ORGS **
|
73
73
|
* access with ORGS or ORGS
|
74
74
|
* access a specific org: ORGS['orgname']
|
data/lib/chef_fixie/context.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2015 Chef Software Inc.
|
2
|
+
# Copyright (c) 2015 Chef Software Inc.
|
3
3
|
# License :: Apache License, Version 2.0
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -18,9 +18,8 @@
|
|
18
18
|
#
|
19
19
|
# Much of this code was orginally derived from the orgmapper tool, which had many varied authors.
|
20
20
|
|
21
|
-
|
22
21
|
module ChefFixie
|
23
|
-
|
22
|
+
module Context
|
24
23
|
|
25
24
|
def describe_orgs
|
26
25
|
OrgMetrics.org_stats(orgs)
|
@@ -67,6 +66,5 @@ module ChefFixie
|
|
67
66
|
|
68
67
|
ChefFixie::Dissociator.dissociate_user(org, user)
|
69
68
|
end
|
70
|
-
|
71
69
|
end
|
72
70
|
end
|
data/lib/chef_fixie/sql.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2014-2015 Chef Software Inc.
|
2
|
+
# Copyright (c) 2014-2015 Chef Software Inc.
|
3
3
|
# License :: Apache License, Version 2.0
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,20 +16,20 @@
|
|
16
16
|
#
|
17
17
|
# Author: Mark Anderson <mark@chef.io>
|
18
18
|
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
19
|
+
require "ffi_yajl"
|
20
|
+
require "uuidtools"
|
21
|
+
require "sequel"
|
22
22
|
|
23
|
-
require_relative
|
23
|
+
require_relative "config"
|
24
24
|
|
25
25
|
Sequel.default_timezone = :utc
|
26
26
|
|
27
27
|
module ChefFixie
|
28
28
|
module Sql
|
29
|
-
|
29
|
+
|
30
30
|
class InvalidConfig < StandardError
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# A connection string passed to Sequel.connect()
|
34
34
|
#
|
35
35
|
# Examples:
|
@@ -46,25 +46,25 @@ module ChefFixie
|
|
46
46
|
|
47
47
|
# Returns the connection string or raises an error if you didn't set one.
|
48
48
|
def self.connection_string
|
49
|
-
@connection_string ||= ChefFixie.configure {|x| x.sql_database }
|
49
|
+
@connection_string ||= ChefFixie.configure { |x| x.sql_database }
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
# Returns a Sequel::Data baseobject, which wraps access to the database.
|
53
53
|
def self.default_connection
|
54
54
|
@database ||= Sequel.connect(connection_string, :max_connections => 2)
|
55
55
|
# @database.loggers << Logger.new($stdout)
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
# Generate a new UUID. Currently uses the v1 UUID scheme.
|
59
59
|
def new_uuid
|
60
60
|
UUIDTools::UUID.timestamp_create.hexdigest
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# Parse the portion of the object that's stored as a blob o' JSON
|
64
64
|
def from_json(serialized_data)
|
65
65
|
FFI_Yajl::Parser.parse(serialized_data, :symbolize_keys => true)
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
# Encode the portion of the object that's stored as a blob o' JSON
|
69
69
|
def as_json(data)
|
70
70
|
FFI_Yajl::Encoder.encode(data)
|
@@ -17,12 +17,12 @@
|
|
17
17
|
# Author: Mark Anderson <mark@chef.io>
|
18
18
|
#
|
19
19
|
|
20
|
-
require
|
21
|
-
require
|
20
|
+
require "pp"
|
21
|
+
require "sequel"
|
22
22
|
|
23
|
-
require_relative
|
24
|
-
require_relative
|
25
|
-
require_relative
|
23
|
+
require_relative "config"
|
24
|
+
require_relative "authz_objects"
|
25
|
+
require_relative "authz_mapper"
|
26
26
|
|
27
27
|
Sequel.extension :inflector
|
28
28
|
|
@@ -51,25 +51,28 @@ module ChefFixie
|
|
51
51
|
else
|
52
52
|
class_or_name.class.to_s
|
53
53
|
end
|
54
|
-
name.split(
|
54
|
+
name.split("::")[-1]
|
55
55
|
end
|
56
56
|
|
57
57
|
# The class for the table, e.g. Orgs
|
58
58
|
def self.table_class(name)
|
59
|
-
name =
|
59
|
+
name = to_name(name)
|
60
60
|
(base + name.to_s.pluralize.camelize).constantize
|
61
61
|
end
|
62
|
+
|
62
63
|
# The class for one instance of the object, e.g. Org
|
63
64
|
def self.object_class(name)
|
64
|
-
name =
|
65
|
+
name = to_name(name)
|
65
66
|
(base + name.to_s.singularize.camelize).constantize
|
66
67
|
end
|
68
|
+
|
67
69
|
def self.singular(name)
|
68
|
-
name =
|
70
|
+
name = to_name(name)
|
69
71
|
name.to_s.singularize
|
70
72
|
end
|
73
|
+
|
71
74
|
def self.plural(name)
|
72
|
-
name =
|
75
|
+
name = to_name(name)
|
73
76
|
name.to_s.pluralize
|
74
77
|
end
|
75
78
|
end
|
@@ -79,9 +82,11 @@ module ChefFixie
|
|
79
82
|
def initialize(data)
|
80
83
|
@data = data
|
81
84
|
end
|
85
|
+
|
82
86
|
def data
|
83
87
|
@data
|
84
88
|
end
|
89
|
+
|
85
90
|
def table
|
86
91
|
Relationships.table_class(self).new
|
87
92
|
end
|
@@ -90,26 +95,27 @@ module ChefFixie
|
|
90
95
|
def self.ro_access(*args)
|
91
96
|
args.each do |field|
|
92
97
|
fundef = "def #{field}; @data.#{field}; end"
|
93
|
-
|
98
|
+
class_eval(fundef)
|
94
99
|
end
|
95
100
|
end
|
96
101
|
# TODO figure out model for write access
|
97
102
|
|
98
103
|
def self.name_field(field)
|
99
104
|
fundef = "def name; @data.#{field}; end"
|
100
|
-
|
105
|
+
class_eval(fundef)
|
101
106
|
end
|
102
107
|
|
103
108
|
def self.std_timestamp
|
104
109
|
[:created_at, :updated_at].each do |i|
|
105
|
-
|
110
|
+
ro_access(i)
|
106
111
|
end
|
107
112
|
end
|
113
|
+
|
108
114
|
# Pretty much any object with an authz id has these fields
|
109
115
|
def self.std_authz
|
110
|
-
|
116
|
+
std_timestamp
|
111
117
|
[:authz_id, :last_updated_by].each do |i|
|
112
|
-
|
118
|
+
ro_access(i)
|
113
119
|
end
|
114
120
|
end
|
115
121
|
|
@@ -117,7 +123,7 @@ module ChefFixie
|
|
117
123
|
rows = table.by_id(id)
|
118
124
|
raise "id #{id} matches more than one object" if rows.all.count != 1
|
119
125
|
rows.inner.delete
|
120
|
-
if
|
126
|
+
if respond_to?(:authz_delete)
|
121
127
|
authz_delete
|
122
128
|
end
|
123
129
|
end
|
@@ -131,13 +137,14 @@ module ChefFixie
|
|
131
137
|
funname = Relationships.plural(object)
|
132
138
|
# defer evaluation of mapper to make sure we have a chance for everyone to initialize
|
133
139
|
fundef = "def #{funname}; Relationships.table_class(:#{object}).new.by_org_id(org_id); end"
|
134
|
-
|
140
|
+
class_eval(fundef)
|
135
141
|
end
|
136
142
|
end
|
137
143
|
|
138
144
|
def initialize(data)
|
139
145
|
super(data)
|
140
146
|
end
|
147
|
+
|
141
148
|
def org_id
|
142
149
|
data[:id]
|
143
150
|
end
|
@@ -158,7 +165,7 @@ module ChefFixie
|
|
158
165
|
# TODO Write some tests to validate that this stuff
|
159
166
|
# works, since it depends on a lot of name magic...
|
160
167
|
|
161
|
-
NAME_FIXUP = {"data" => "data_bags", "sandboxes" => nil}
|
168
|
+
NAME_FIXUP = { "data" => "data_bags", "sandboxes" => nil }
|
162
169
|
def objects_by_container_type(container)
|
163
170
|
name = NAME_FIXUP.has_key?(container) ? NAME_FIXUP[container] : container
|
164
171
|
return [] if name.nil?
|
@@ -176,7 +183,7 @@ module ChefFixie
|
|
176
183
|
yield objects
|
177
184
|
end
|
178
185
|
end
|
179
|
-
|
186
|
+
nil
|
180
187
|
end
|
181
188
|
|
182
189
|
def each_authz_object
|
@@ -185,7 +192,7 @@ module ChefFixie
|
|
185
192
|
yield object
|
186
193
|
end
|
187
194
|
end
|
188
|
-
|
195
|
+
nil
|
189
196
|
end
|
190
197
|
|
191
198
|
scoped_type :container, :group, :client,
|
@@ -257,7 +264,6 @@ module ChefFixie
|
|
257
264
|
# org_migration_state_id_seq policy_revisions
|
258
265
|
# policy_revisions_policy_groups_association sandboxed_checksums
|
259
266
|
|
260
|
-
|
261
267
|
class CookbookArtifact < SqlObject
|
262
268
|
include AuthzObjectMixin
|
263
269
|
def initialize(data)
|
@@ -342,31 +348,33 @@ module ChefFixie
|
|
342
348
|
def get_table
|
343
349
|
:unknown_table
|
344
350
|
end
|
351
|
+
|
345
352
|
def mk_element(x)
|
346
353
|
x
|
347
354
|
end
|
348
355
|
|
349
356
|
def initialize(tablespec = nil)
|
350
357
|
ChefFixie::Sql.default_connection
|
351
|
-
@inner = tablespec || Sequel::Model(
|
358
|
+
@inner = tablespec || Sequel::Model(get_table)
|
352
359
|
end
|
360
|
+
|
353
361
|
def inner
|
354
362
|
# Make sure we have init
|
355
363
|
@inner
|
356
364
|
end
|
357
365
|
|
358
366
|
def filter_core(field, exp)
|
359
|
-
self.class.new(inner.filter(field=>exp))
|
367
|
+
self.class.new(inner.filter(field => exp))
|
360
368
|
end
|
361
369
|
|
362
|
-
def all(max_count
|
370
|
+
def all(max_count = :default)
|
363
371
|
if max_count == :default
|
364
372
|
max_count = ChefFixie::Sql::SqlTable.max_count_default
|
365
373
|
end
|
366
374
|
if max_count != :all
|
367
|
-
return :too_many_results if
|
375
|
+
return :too_many_results if inner.count > max_count
|
368
376
|
end
|
369
|
-
elements = inner.all.map {|org| mk_element(org) }
|
377
|
+
elements = inner.all.map { |org| mk_element(org) }
|
370
378
|
end
|
371
379
|
|
372
380
|
#
|
@@ -375,7 +383,7 @@ module ChefFixie
|
|
375
383
|
# https://stackoverflow.com/questions/9658724/ruby-metaprogramming-class-eval/9658775#9658775
|
376
384
|
def self.primary(arg)
|
377
385
|
name = :"by_#{arg}"
|
378
|
-
|
386
|
+
class_eval("def [](arg); #{name}(arg).all(1).first; end")
|
379
387
|
|
380
388
|
listfun = <<EOLF
|
381
389
|
def list(max_count=:default)
|
@@ -387,26 +395,27 @@ def list(max_count=:default)
|
|
387
395
|
end
|
388
396
|
end
|
389
397
|
EOLF
|
390
|
-
|
398
|
+
class_eval(listfun)
|
391
399
|
end
|
392
400
|
|
393
401
|
def self.filter_by(*args)
|
394
402
|
args.each do |field|
|
395
403
|
name = "by_#{field}"
|
396
404
|
fundef = "def #{name}(exp); filter_core(:#{field},exp); end"
|
397
|
-
|
405
|
+
class_eval(fundef)
|
398
406
|
end
|
399
407
|
end
|
400
408
|
|
401
409
|
def self.table(name)
|
402
410
|
fundef = "def get_table; :#{name}; end"
|
403
|
-
|
411
|
+
class_eval(fundef)
|
404
412
|
end
|
413
|
+
|
405
414
|
# doesn't work yet
|
406
415
|
# element Org in class Orgs will fail because it can't find Org (undefined)
|
407
416
|
def self.element(name)
|
408
417
|
fundef = "ElementType = name; def mk_element(x); #{name}.new(x); end"
|
409
|
-
|
418
|
+
class_eval(fundef)
|
410
419
|
end
|
411
420
|
end
|
412
421
|
|
@@ -418,7 +427,7 @@ EOLF
|
|
418
427
|
primary :name
|
419
428
|
filter_by :name, :id, :full_name, :authz_id
|
420
429
|
|
421
|
-
GlobalOrg = "0"*32
|
430
|
+
GlobalOrg = "0" * 32
|
422
431
|
|
423
432
|
def self.org_guid_to_name(guid)
|
424
433
|
"global" if guid == GlobalOrg
|
@@ -439,7 +448,7 @@ EOLF
|
|
439
448
|
|
440
449
|
def by_org_id_user_id(org_id, user_id)
|
441
450
|
# db table constraint guarantees that this is unique
|
442
|
-
inner.filter(:org_id=>org_id, :user_id=>user_id).all.first
|
451
|
+
inner.filter(:org_id => org_id, :user_id => user_id).all.first
|
443
452
|
end
|
444
453
|
|
445
454
|
end
|
@@ -449,7 +458,7 @@ EOLF
|
|
449
458
|
|
450
459
|
def by_org_id_user_id(org_id, user_id)
|
451
460
|
# db table constraint guarantees that this is unique
|
452
|
-
inner.filter(:org_id=>org_id, :user_id=>user_id).all.first
|
461
|
+
inner.filter(:org_id => org_id, :user_id => user_id).all.first
|
453
462
|
end
|
454
463
|
end
|
455
464
|
class Users < SqlTable
|
@@ -551,7 +560,7 @@ EOLF
|
|
551
560
|
filter_by :name, :id, :org_id, :authz_id
|
552
561
|
end
|
553
562
|
|
554
|
-
class Roles
|
563
|
+
class Roles < SqlTable
|
555
564
|
table :roles
|
556
565
|
element Sql::Role
|
557
566
|
register_authz :role, :object
|
@@ -560,7 +569,5 @@ EOLF
|
|
560
569
|
filter_by :name, :id, :org_id, :authz_id, :last_updated_by
|
561
570
|
end
|
562
571
|
|
563
|
-
|
564
|
-
|
565
572
|
end
|
566
573
|
end
|