chef_fixie 0.1.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +69 -0
  4. data/bin/bundler +16 -0
  5. data/bin/chef-apply +16 -0
  6. data/bin/chef-client +16 -0
  7. data/bin/chef-shell +16 -0
  8. data/bin/chef-solo +16 -0
  9. data/bin/chef-zero +16 -0
  10. data/bin/chef_fixie +5 -0
  11. data/bin/coderay +16 -0
  12. data/bin/edit_json.rb +16 -0
  13. data/bin/erubis +16 -0
  14. data/bin/ffi-yajl-bench +16 -0
  15. data/bin/fixie~ +231 -0
  16. data/bin/htmldiff +16 -0
  17. data/bin/knife +16 -0
  18. data/bin/ldiff +16 -0
  19. data/bin/net-dhcp +16 -0
  20. data/bin/ohai +16 -0
  21. data/bin/prettify_json.rb +16 -0
  22. data/bin/pry +16 -0
  23. data/bin/rackup +16 -0
  24. data/bin/rake +16 -0
  25. data/bin/rdoc +16 -0
  26. data/bin/restclient +16 -0
  27. data/bin/ri +16 -0
  28. data/bin/rspec +16 -0
  29. data/bin/s3sh +16 -0
  30. data/bin/sequel +16 -0
  31. data/bin/serverspec-init +16 -0
  32. data/doc/AccessingSQL.md +36 -0
  33. data/doc/AccessingSQL.md~ +32 -0
  34. data/doc/BulkFixup.md~ +28 -0
  35. data/doc/CommonTasks.md +20 -0
  36. data/doc/CommonTasks.md~ +0 -0
  37. data/doc/GETTING_STARTED.md +228 -0
  38. data/doc/GETTING_STARTED.md~ +6 -0
  39. data/fixie.conf.example +8 -0
  40. data/lib/chef_fixie.rb +27 -0
  41. data/lib/chef_fixie/authz_mapper.rb +143 -0
  42. data/lib/chef_fixie/authz_objects.rb +285 -0
  43. data/lib/chef_fixie/check_org_associations.rb +242 -0
  44. data/lib/chef_fixie/config.rb +139 -0
  45. data/lib/chef_fixie/console.rb +91 -0
  46. data/lib/chef_fixie/context.rb +72 -0
  47. data/lib/chef_fixie/sql.rb +74 -0
  48. data/lib/chef_fixie/sql_objects.rb +497 -0
  49. data/lib/chef_fixie/utility_helpers.rb +59 -0
  50. data/lib/chef_fixie/version.rb +3 -0
  51. data/spec/chef_fixie/acl_spec.rb +83 -0
  52. data/spec/chef_fixie/assoc_invite_spec.rb +47 -0
  53. data/spec/chef_fixie/assoc_invite_spec.rb~ +26 -0
  54. data/spec/chef_fixie/check_org_associations_spec.rb +140 -0
  55. data/spec/chef_fixie/check_org_associations_spec.rb~ +34 -0
  56. data/spec/chef_fixie/groups_spec.rb +34 -0
  57. data/spec/chef_fixie/org_spec.rb +26 -0
  58. data/spec/chef_fixie/org_spec.rb~ +53 -0
  59. data/spec/chef_fixie/orgs_spec.rb +53 -0
  60. data/spec/spec_helper.rb +41 -0
  61. metadata +252 -0
@@ -0,0 +1,72 @@
1
+ #
2
+ # Copyright (c) 2015 Chef Software Inc.
3
+ # License :: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Author: Mark Anderson <mark@chef.io>
18
+ #
19
+ # Much of this code was orginally derived from the orgmapper tool, which had many varied authors.
20
+
21
+
22
+ module ChefFixie
23
+ module Context
24
+
25
+ def describe_orgs
26
+ OrgMetrics.org_stats(orgs)
27
+ end
28
+
29
+ def orgs
30
+ ChefFixie::Organizations.new
31
+ end
32
+
33
+ def jobs
34
+ ChefFixie::Jobs.new
35
+ end
36
+
37
+ def users
38
+ ChefFixie::Users.new
39
+ end
40
+
41
+ def global_groups
42
+ ChefFixie::GlobalGroups.new
43
+ end
44
+
45
+ def sql
46
+ ChefFixie::Sql.default_connection
47
+ end
48
+
49
+ def associate_user(username, orgname)
50
+ unless user = users.find(username)
51
+ raise ArgumentError, "No users matched '#{username}'"
52
+ end
53
+ unless org = ORGS[orgname]
54
+ raise ArgumentError, "No orgs matched '#{orgname}'"
55
+ end
56
+
57
+ ChefFixie::Associator.associate_user(org, user)
58
+ end
59
+
60
+ def dissociate_user(username, orgname)
61
+ unless user = users.find(username)
62
+ raise ArgumentError, "No users matched '#{username}'"
63
+ end
64
+ unless org = ORGS[orgname]
65
+ raise ArgumentError, "No orgs matched '#{orgname}'"
66
+ end
67
+
68
+ ChefFixie::Dissociator.dissociate_user(org, user)
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,74 @@
1
+ #
2
+ # Copyright (c) 2014-2015 Chef Software Inc.
3
+ # License :: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Author: Mark Anderson <mark@chef.io>
18
+
19
+ require 'ffi_yajl'
20
+ require 'uuidtools'
21
+ require 'sequel'
22
+
23
+ require 'chef_fixie/config'
24
+
25
+ Sequel.default_timezone = :utc
26
+
27
+ module ChefFixie
28
+ module Sql
29
+
30
+ class InvalidConfig < StandardError
31
+ end
32
+
33
+ # A connection string passed to Sequel.connect()
34
+ #
35
+ # Examples:
36
+ # * "mysql2://root@localhost/opscode_chef"
37
+ # * "mysql2://user:password@host/opscode_chef"
38
+ # * "jdbc:mysql://localhost/test?user=root&password=root"
39
+ #
40
+ # See also: http://sequel.rubyforge.org/rdoc/files/doc/opening_databases_rdoc.html
41
+ def self.connection_string=(sequel_connection_string)
42
+ @database.disconnect if @database.respond_to?(:disconnect)
43
+ @database = nil
44
+ @connection_string = sequel_connection_string
45
+ end
46
+
47
+ # Returns the connection string or raises an error if you didn't set one.
48
+ def self.connection_string
49
+ @connection_string ||= ChefFixie.configure {|x| x.sql_database }
50
+ end
51
+
52
+ # Returns a Sequel::Data baseobject, which wraps access to the database.
53
+ def self.default_connection
54
+ @database ||= Sequel.connect(connection_string, :max_connections => 2)
55
+ # @database.loggers << Logger.new($stdout)
56
+ end
57
+
58
+ # Generate a new UUID. Currently uses the v1 UUID scheme.
59
+ def new_uuid
60
+ UUIDTools::UUID.timestamp_create.hexdigest
61
+ end
62
+
63
+ # Parse the portion of the object that's stored as a blob o' JSON
64
+ def from_json(serialized_data)
65
+ FFI_Yajl::Parser.parse(serialized_data, :symbolize_keys => true)
66
+ end
67
+
68
+ # Encode the portion of the object that's stored as a blob o' JSON
69
+ def as_json(data)
70
+ FFI_Yajl::Encoder.encode(data)
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,497 @@
1
+ #
2
+ # Copyright (c) 2014-2015 Chef Software Inc.
3
+ # License :: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ # Author: Mark Anderson <mark@chef.io>
18
+ #
19
+
20
+ require 'pp'
21
+ require 'sequel'
22
+
23
+ require 'chef_fixie/config'
24
+ require 'chef_fixie/authz_objects'
25
+ require 'chef_fixie/authz_mapper'
26
+
27
+ Sequel.extension :inflector
28
+
29
+ module ChefFixie
30
+ module Sql
31
+
32
+ # Maps entity names like 'org' to the table class (Orgs) and the entity class (Org), as well as the cannonical
33
+ # each table has a name, a class to wrap the table, an row, and a class to map the row.
34
+ # Wrapping this in a class to handle things if we have to not be consisitent with our naming.
35
+ # table :orgs, class wrapper Orgs, row :org, class for row Org
36
+ module Relationships
37
+
38
+ def self.base
39
+ "ChefFixie::Sql" + "::" # this should be autogenerated not hardcoded
40
+ end
41
+
42
+ # The class for the table, e.g. Orgs
43
+ def self.table_class(name)
44
+ (base + name.to_s.pluralize.camelize).constantize
45
+ end
46
+ # The class for one instance of the object, e.g. Org
47
+ def self.object_class(name)
48
+ (base + name.to_s.singularize.camelize).constantize
49
+ end
50
+ def self.singular(name)
51
+ name.to_s.singularize
52
+ end
53
+ def self.plural(name)
54
+ name.to_s.pluralize
55
+ end
56
+ end
57
+
58
+ # we declare these first so that the 'element' metaprogramming in SqlTable works
59
+ class SqlObject
60
+ def initialize(data)
61
+ @data = data
62
+ end
63
+ def data
64
+ @data
65
+ end
66
+
67
+ # TODO rework this to use better style
68
+ def self.ro_access(*args)
69
+ args.each do |field|
70
+ fundef = "def #{field}; @data.#{field}; end"
71
+ self.class_eval(fundef)
72
+ end
73
+ end
74
+ # TODO figure out model for write access
75
+
76
+ def self.name_field(field)
77
+ fundef = "def name; @data.#{field}; end"
78
+ self.class_eval(fundef)
79
+ end
80
+
81
+ def self.std_timestamp
82
+ [:created_at, :updated_at].each do |i|
83
+ self.ro_access(i)
84
+ end
85
+ end
86
+ # Pretty much any object with an authz id has these fields
87
+ def self.std_authz
88
+ self.std_timestamp
89
+ [:authz_id, :last_updated_by].each do |i|
90
+ self.ro_access(i)
91
+ end
92
+ end
93
+
94
+
95
+ end
96
+
97
+ class Org < SqlObject
98
+ include AuthzObjectMixin
99
+
100
+ def self.scoped_type(*args)
101
+ args.each do |object|
102
+ funname = Relationships.plural(object)
103
+ # defer evaluation of mapper to make sure we have a chance for everyone to initialize
104
+ fundef = "def #{funname}; Relationships.table_class(:#{object}).new.by_org_id(org_id); end"
105
+ self.class_eval(fundef)
106
+ end
107
+ end
108
+
109
+ def initialize(data)
110
+ super(data)
111
+ end
112
+ def org_id
113
+ data[:id]
114
+ end
115
+
116
+ def global_admins
117
+ name = self.name
118
+ global_admins_name = "#{name}_global_admins"
119
+ ChefFixie::Sql::Groups.new["#{name}_global_admins"]
120
+ end
121
+
122
+ scoped_type :container, :group, :client,
123
+ :cookbook_artifact, :cookbook, :data_bag, :environment, :node, :policy, :policy_group , :role
124
+
125
+ # Maybe autogenerate this from data.columns?
126
+ ro_access :id, :authz_id, :assigned_at, :last_updated_by, :created_at, :updated_at, :name, :full_name
127
+ end
128
+
129
+ #
130
+ # Some types have an org_id field and may be scoped to an org (some, like groups are able to be global as well)
131
+ # This sets up a filtered accessor that limits
132
+ #
133
+ # module ScopedType
134
+ # def self.included(base)
135
+ # pp :base=>base
136
+ # Org.scoped_type(base)
137
+ # end
138
+ # end
139
+
140
+ class Container < SqlObject
141
+ include AuthzContainerMixin
142
+
143
+ def initialize(data)
144
+ super(data)
145
+ end
146
+
147
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name
148
+ end
149
+ class Group < SqlObject
150
+ include AuthzGroupMixin
151
+
152
+ def initialize(data)
153
+ super(data)
154
+ end
155
+
156
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name
157
+ end
158
+
159
+ class User < SqlObject
160
+ include AuthzActorMixin
161
+ def initialize(data)
162
+ super(data)
163
+ end
164
+ name_field :username
165
+ ro_access :id, :authz_id, :last_updated_by, :created_at, :updated_at, :username, :email, :public_key, :pubkey_version, :serialized_object, :external_authentication_uid, :recovery_authentication_enabled, :admin, :hashed_password, :salt, :hash_type
166
+ end
167
+ class Client < SqlObject
168
+ include AuthzActorMixin
169
+ def initialize(data)
170
+ super(data)
171
+ end
172
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name
173
+ end
174
+
175
+ # Objects
176
+
177
+ # At the time of writing there are more objects in sql than we
178
+ # support here; we should add them. We have only covered the
179
+ # objects that have their own authz info
180
+ # Missing objects include:
181
+ # checksums cookbook_artifact_version_checksums
182
+ # cookbook_artifact_versions cookbook_artifact_versions_id_seq
183
+ # cookbook_artifacts_id_seq cookbook_version_checksums
184
+ # cookbook_version_dependencies cookbook_versions
185
+ # cookbook_versions_by_rank cookbooks_id_seq data_bag_items
186
+ # joined_cookbook_version keys keys_by_name node_policy opc_customers
187
+ # opc_customers_id_seq opc_users org_migration_state
188
+ # org_migration_state_id_seq policy_revisions
189
+ # policy_revisions_policy_groups_association sandboxed_checksums
190
+
191
+
192
+ class CookbookArtifact < SqlObject
193
+ include AuthzObjectMixin
194
+ def initialize(data)
195
+ super(data)
196
+ end
197
+ ro_access :id, :org_id, :authz_id, :name
198
+ end
199
+
200
+ class Cookbook < SqlObject
201
+ include AuthzObjectMixin
202
+ def initialize(data)
203
+ super(data)
204
+ end
205
+ ro_access :id, :org_id, :authz_id, :name
206
+ end
207
+
208
+ class DataBag < SqlObject
209
+ include AuthzObjectMixin
210
+ def initialize(data)
211
+ super(data)
212
+ end
213
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name
214
+ end
215
+
216
+ # data bag item needs some prep work to do since it doesn't have authz stuff.
217
+
218
+ class Environment < SqlObject
219
+ include AuthzObjectMixin
220
+ def initialize(data)
221
+ super(data)
222
+ end
223
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name, :serialized_object
224
+ # serialized_object requires work since most of the time it isn't wanted
225
+ end
226
+
227
+ class Node < SqlObject
228
+ include AuthzObjectMixin
229
+ def initialize(data)
230
+ super(data)
231
+ end
232
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name, :serialized_object
233
+ # serialized_object requires work since most of the time it isn't wanted
234
+ end
235
+
236
+ class Policy < SqlObject
237
+ include AuthzObjectMixin
238
+ def initialize(data)
239
+ super(data)
240
+ end
241
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :name
242
+ # serialized_object requires work since most of the time it isn't wanted
243
+ end
244
+
245
+ class PolicyGroup < SqlObject
246
+ include AuthzObjectMixin
247
+ def initialize(data)
248
+ super(data)
249
+ end
250
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :name, :serialized_object
251
+ # serialized_object requires work since most of the time it isn't wanted
252
+ end
253
+
254
+ class Role < SqlObject
255
+ include AuthzObjectMixin
256
+ def initialize(data)
257
+ super(data)
258
+ end
259
+ ro_access :id, :org_id, :authz_id, :last_updated_by, :created_at, :updated_at, :name, :serialized_object
260
+ # serialized_object requires work since most of the time it isn't wanted
261
+ end
262
+
263
+ #
264
+ #
265
+ #
266
+ class SqlTable
267
+ include AuthzMapper
268
+
269
+ def self.max_count_default
270
+ 50
271
+ end
272
+
273
+ def get_table
274
+ :unknown_table
275
+ end
276
+ def mk_element(x)
277
+ x
278
+ end
279
+
280
+ def initialize(tablespec = nil)
281
+ ChefFixie::Sql.default_connection
282
+ @inner = tablespec || Sequel::Model(self.get_table)
283
+ end
284
+ def inner
285
+ # Make sure we have init
286
+ @inner
287
+ end
288
+
289
+ def filter_core(field, exp)
290
+ self.class.new(inner.filter(field=>exp))
291
+ end
292
+
293
+ def all(max_count=:default)
294
+ if max_count == :default
295
+ max_count = ChefFixie::Sql::SqlTable.max_count_default
296
+ end
297
+ if max_count != :all
298
+ return :too_many_results if (inner.count > max_count)
299
+ end
300
+ elements = inner.all.map {|org| mk_element(org) }
301
+ end
302
+
303
+ #
304
+ # TODO Improve these via define_method
305
+ # See http://blog.jayfields.com/2007/10/ruby-defining-class-methods.html
306
+ # https://stackoverflow.com/questions/9658724/ruby-metaprogramming-class-eval/9658775#9658775
307
+ def self.primary(arg)
308
+ name = :"by_#{arg}"
309
+ self.class_eval("def [](arg); #{name}(arg).all(1).first; end")
310
+
311
+ listfun = <<EOLF
312
+ def list(max_count=:default)
313
+ elements = all(max_count)
314
+ if elements == :too_many_results
315
+ elements
316
+ else
317
+ elements.map {|e| e.#{arg} }.sort
318
+ end
319
+ end
320
+ EOLF
321
+ self.class_eval(listfun)
322
+ end
323
+
324
+ def self.filter_by(*args)
325
+ args.each do |field|
326
+ name = "by_#{field}"
327
+ fundef = "def #{name}(exp); filter_core(:#{field},exp); end"
328
+ self.class_eval(fundef)
329
+ end
330
+ end
331
+
332
+ def self.table(name)
333
+ fundef = "def get_table; :#{name}; end"
334
+ self.class_eval(fundef)
335
+ end
336
+ # doesn't work yet
337
+ # element Org in class Orgs will fail because it can't find Org (undefined)
338
+ def self.element(name)
339
+ fundef = "ElementType = name; def mk_element(x); #{name}.new(x); end"
340
+ self.class_eval(fundef)
341
+ end
342
+ end
343
+
344
+ class Orgs < SqlTable
345
+ table :orgs
346
+ element Sql::Org
347
+ register_authz :org, :object
348
+
349
+ primary :name
350
+ filter_by :name, :id, :full_name, :authz_id
351
+
352
+ GlobalOrg = "0"*32
353
+
354
+ def self.org_guid_to_name(guid)
355
+ "global" if guid == GlobalOrg
356
+ # Cache the class
357
+ @orgs ||= Orgs.new
358
+ names = @orgs.by_id(guid).all(1)
359
+ if names.count == 1
360
+ names.first.name
361
+ else
362
+ "unknown-#{guid}"
363
+ end
364
+ end
365
+ end
366
+
367
+ class Associations < SqlTable
368
+ table :org_user_associations
369
+ filter_by :org_id, :user_id, :last_updated_by
370
+
371
+ def by_org_id_user_id(org_id, user_id)
372
+ # db table constraint guarantees that this is unique
373
+ inner.filter(:org_id=>org_id, :user_id=>user_id).all.first
374
+ end
375
+
376
+ end
377
+ class Invites < SqlTable
378
+ table :org_user_invites
379
+ filter_by :org_id, :user_id, :last_updated_by
380
+
381
+ def by_org_id_user_id(org_id, user_id)
382
+ # db table constraint guarantees that this is unique
383
+ inner.filter(:org_id=>org_id, :user_id=>user_id).all.first
384
+ end
385
+ end
386
+ class Users < SqlTable
387
+ table :users
388
+ element Sql::User
389
+ register_authz :user, :actor
390
+
391
+ primary :username
392
+ filter_by :id, :authz_id, :username, :email
393
+ end
394
+ class Clients < SqlTable
395
+ table :clients
396
+ element Sql::Client
397
+ register_authz :client, :actor
398
+
399
+ primary :name
400
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
401
+ end
402
+
403
+ class Containers < SqlTable
404
+ table :containers
405
+ element Sql::Container
406
+ register_authz :container, :container
407
+
408
+ primary :name
409
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
410
+ end
411
+ class Groups < SqlTable
412
+ table :groups
413
+ element Sql::Group
414
+ register_authz :group, :group
415
+
416
+ primary :name
417
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
418
+ end
419
+
420
+ # Objects
421
+ # todo check
422
+ class CookbookArtifacts < SqlTable
423
+ table :cookbook_artifacts
424
+ element Sql::CookbookArtifact
425
+ register_authz :cookbook_artifact, :object
426
+
427
+ primary :name
428
+ filter_by :name, :id, :org_id, :authz_id
429
+ end
430
+
431
+ class Cookbooks < SqlTable
432
+ table :cookbooks
433
+ element Sql::Cookbook
434
+ register_authz :cookbook, :object
435
+
436
+ primary :name
437
+ filter_by :name, :id, :org_id, :authz_id
438
+ end
439
+
440
+ class DataBags < SqlTable
441
+ table :data_bags
442
+ element Sql::DataBag
443
+ register_authz :data_bag, :object
444
+
445
+ primary :name
446
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
447
+ end
448
+
449
+ class Environments < SqlTable
450
+ table :environments
451
+ element Sql::Environment
452
+ register_authz :environment, :object
453
+
454
+ primary :name
455
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
456
+ end
457
+
458
+ class Nodes < SqlTable
459
+ table :nodes
460
+ element Sql::Node
461
+ register_authz :node, :object
462
+
463
+ primary :name
464
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
465
+ end
466
+
467
+ class Policies < SqlTable
468
+ table :policies
469
+ element Sql::Policy
470
+ register_authz :policy, :object
471
+
472
+ primary :name
473
+ filter_by :name, :id, :org_id, :authz_id
474
+ end
475
+
476
+ class PolicyGroups < SqlTable
477
+ table :policy_groups
478
+ element Sql::PolicyGroup
479
+ register_authz :policygroup, :object
480
+
481
+ primary :name
482
+ filter_by :name, :id, :org_id, :authz_id
483
+ end
484
+
485
+ class Roles < SqlTable
486
+ table :roles
487
+ element Sql::Role
488
+ register_authz :role, :object
489
+
490
+ primary :name
491
+ filter_by :name, :id, :org_id, :authz_id, :last_updated_by
492
+ end
493
+
494
+
495
+
496
+ end
497
+ end