chef_fixie 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/README.md +69 -0
- data/bin/bundler +16 -0
- data/bin/chef-apply +16 -0
- data/bin/chef-client +16 -0
- data/bin/chef-shell +16 -0
- data/bin/chef-solo +16 -0
- data/bin/chef-zero +16 -0
- data/bin/chef_fixie +5 -0
- data/bin/coderay +16 -0
- data/bin/edit_json.rb +16 -0
- data/bin/erubis +16 -0
- data/bin/ffi-yajl-bench +16 -0
- data/bin/fixie~ +231 -0
- data/bin/htmldiff +16 -0
- data/bin/knife +16 -0
- data/bin/ldiff +16 -0
- data/bin/net-dhcp +16 -0
- data/bin/ohai +16 -0
- data/bin/prettify_json.rb +16 -0
- data/bin/pry +16 -0
- data/bin/rackup +16 -0
- data/bin/rake +16 -0
- data/bin/rdoc +16 -0
- data/bin/restclient +16 -0
- data/bin/ri +16 -0
- data/bin/rspec +16 -0
- data/bin/s3sh +16 -0
- data/bin/sequel +16 -0
- data/bin/serverspec-init +16 -0
- data/doc/AccessingSQL.md +36 -0
- data/doc/AccessingSQL.md~ +32 -0
- data/doc/BulkFixup.md~ +28 -0
- data/doc/CommonTasks.md +20 -0
- data/doc/CommonTasks.md~ +0 -0
- data/doc/GETTING_STARTED.md +228 -0
- data/doc/GETTING_STARTED.md~ +6 -0
- data/fixie.conf.example +8 -0
- data/lib/chef_fixie.rb +27 -0
- data/lib/chef_fixie/authz_mapper.rb +143 -0
- data/lib/chef_fixie/authz_objects.rb +285 -0
- data/lib/chef_fixie/check_org_associations.rb +242 -0
- data/lib/chef_fixie/config.rb +139 -0
- data/lib/chef_fixie/console.rb +91 -0
- data/lib/chef_fixie/context.rb +72 -0
- data/lib/chef_fixie/sql.rb +74 -0
- data/lib/chef_fixie/sql_objects.rb +497 -0
- data/lib/chef_fixie/utility_helpers.rb +59 -0
- data/lib/chef_fixie/version.rb +3 -0
- data/spec/chef_fixie/acl_spec.rb +83 -0
- data/spec/chef_fixie/assoc_invite_spec.rb +47 -0
- data/spec/chef_fixie/assoc_invite_spec.rb~ +26 -0
- data/spec/chef_fixie/check_org_associations_spec.rb +140 -0
- data/spec/chef_fixie/check_org_associations_spec.rb~ +34 -0
- data/spec/chef_fixie/groups_spec.rb +34 -0
- data/spec/chef_fixie/org_spec.rb +26 -0
- data/spec/chef_fixie/org_spec.rb~ +53 -0
- data/spec/chef_fixie/orgs_spec.rb +53 -0
- data/spec/spec_helper.rb +41 -0
- metadata +252 -0
data/bin/ri
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'ri' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rdoc', 'ri')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bin/s3sh
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 's3sh' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('aws-s3', 's3sh')
|
data/bin/sequel
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'sequel' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('sequel', 'sequel')
|
data/bin/serverspec-init
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'serverspec-init' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('serverspec', 'serverspec-init')
|
data/doc/AccessingSQL.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
Basics:
|
3
|
+
-------
|
4
|
+
|
5
|
+
Underneath everything is the Ruby Sequel library; there are a number
|
6
|
+
of ways to access it.
|
7
|
+
|
8
|
+
Check out http://ricostacruz.com/cheatsheets/sequel.html and
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
fixie:0 > o.groups.by_name(cl.id).inner.count
|
15
|
+
1
|
16
|
+
fixie:0 > o.groups.by_name(cl.id).inner.delete
|
17
|
+
1
|
18
|
+
fixie:0 > o.groups.by_name(cl.id).inner.count
|
19
|
+
|
20
|
+
|
21
|
+
* Changing email for user in fixie
|
22
|
+
|
23
|
+
USERS.by_username('anujbiyani').inner.update(:email=>"anujbiyani01@gmail.com")
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
* Adding a record
|
28
|
+
```ruby
|
29
|
+
u=USERS['a_username']
|
30
|
+
o=ORGS['an_org']
|
31
|
+
pivotal = USERS['pivotal']
|
32
|
+
now = Sequel.function(:NOW)
|
33
|
+
|
34
|
+
ASSOCS.inner.insert(:org_id=>o.id, :user_id=>u.id, :last_updated_by=>pivotal.authz_id,
|
35
|
+
:created_at=>now, :updated_at=>now )
|
36
|
+
```
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
Basics:
|
3
|
+
-------
|
4
|
+
|
5
|
+
Underneath everything is the Ruby Sequel library; there are a number
|
6
|
+
of ways to access it.
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
fixie:0 > o.groups.by_name(cl.id).inner.count
|
11
|
+
1
|
12
|
+
fixie:0 > o.groups.by_name(cl.id).inner.delete
|
13
|
+
1
|
14
|
+
fixie:0 > o.groups.by_name(cl.id).inner.count
|
15
|
+
|
16
|
+
|
17
|
+
* Changing email for user in fixie
|
18
|
+
|
19
|
+
USERS.by_username('anujbiyani').inner.update(:email=>"anujbiyani01@gmail.com")
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
* Adding a record
|
24
|
+
```ruby
|
25
|
+
u=USERS['a_username']
|
26
|
+
o=ORGS['an_org']
|
27
|
+
|
28
|
+
pivotal = USERS['pivotal']
|
29
|
+
|
30
|
+
ASSOCS.inner.insert(:org_id=>o.id, :user_id=>u.id, :last_updated_by=>pivotal.authz_id,
|
31
|
+
:created_at=>:NOW.sql_function, :updated_at=>:NOW.sql_function) )
|
32
|
+
```
|
data/doc/BulkFixup.md~
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Restoring acl permissions globally
|
2
|
+
============
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
* If a key group is deleted (such as users)
|
8
|
+
|
9
|
+
Create/restore the group
|
10
|
+
|
11
|
+
Add the users/groups back to the group
|
12
|
+
|
13
|
+
Set the group ACL appropriately
|
14
|
+
|
15
|
+
Restore users to the appropriate container ACLs
|
16
|
+
```ruby
|
17
|
+
o = ORGS[THE_ORG]
|
18
|
+
cl = %w(cookbooks data nodes roles environments policies policy_groups cookbook_artifacts)
|
19
|
+
cl.each {|c| o.containers[c].ace_add([:create,:read,:update,:delete], o.groups['users']) }
|
20
|
+
%w(clients).each { |c| o.containers[c].ace_add([:read,:delete], o.groups['users']) }
|
21
|
+
%w(groups containers).each { |c| o.containers[c].ace_add([:read], o.groups['users']) }
|
22
|
+
%w(sandboxes).each { |c| o.containers[c].ace_add([:create], o.groups['users']) }
|
23
|
+
```
|
24
|
+
|
25
|
+
Then update the objects from the containers:
|
26
|
+
```ruby
|
27
|
+
Fixie::BulkEditPermissions::copy_from_containers(o)
|
28
|
+
```
|
data/doc/CommonTasks.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
Automated organization checkup
|
5
|
+
----------
|
6
|
+
|
7
|
+
If you don't know what's up with an org, there are a few easy starting
|
8
|
+
points
|
9
|
+
|
10
|
+
First of all, run the automated org association checker:
|
11
|
+
|
12
|
+
fixie:0 > Fixie::CheckOrgAssociations.check_associations("acme")
|
13
|
+
Org acme is ok (6 users)
|
14
|
+
|
15
|
+
If it reports a problem with a user, you may be able to fix it
|
16
|
+
automatically:
|
17
|
+
|
18
|
+
fixie:0 > Fixie::CheckOrgAssociations.fix_association("acme", "mary")
|
19
|
+
|
20
|
+
This might need to be run multiple times to fix all of the errors.
|
data/doc/CommonTasks.md~
ADDED
File without changes
|
@@ -0,0 +1,228 @@
|
|
1
|
+
|
2
|
+
Installing fixie
|
3
|
+
-------
|
4
|
+
In the fixie directory, run `bundle install --binstubs`
|
5
|
+
|
6
|
+
Configuring fixie
|
7
|
+
-------
|
8
|
+
|
9
|
+
On chef server installs, fixie can read configuration information out
|
10
|
+
of /etc/opscode, specifically the chef-server-running.json file.
|
11
|
+
|
12
|
+
Otherwise, you will need a fixie.conf file with the appropriate URIs and secrets for
|
13
|
+
accessing postgres and bifrost.
|
14
|
+
|
15
|
+
The fixie.conf.example file contains examples from a instance of
|
16
|
+
private chef.
|
17
|
+
|
18
|
+
| Attribute | Description | Example |
|
19
|
+
|-----------|-------------|---------|
|
20
|
+
| authz_uri | The URI for the bifrost/authz service | http://localhost:9463 |
|
21
|
+
| superuser\_id | The authz superuser id | fa84f0f5524a06baaa10b0f988ff2d8f |
|
22
|
+
| sql\_database | A Ruby Sequel compatible database URI with user and password | postgres://opscode_chef:3b2bb8affc0b87233130f820443aecca2061fadc6c0df16828233e433877ca1c552d1b9d40d3971f0e8c21fc4b7ff9471d91@localhost/opscode_chef |
|
23
|
+
|
24
|
+
Running fixie
|
25
|
+
------
|
26
|
+
|
27
|
+
Start fixie with
|
28
|
+
```shell
|
29
|
+
bin/fixie fixie.conf
|
30
|
+
```
|
31
|
+
The config file is optional, leaving it out will attempt to read
|
32
|
+
/etc/opscode for configuration.
|
33
|
+
|
34
|
+
Inspecting objects
|
35
|
+
------
|
36
|
+
|
37
|
+
There are two core class hierarchies in fixie, one corresponding to a
|
38
|
+
table (e.g. Orgs), and another corresponding to a row in the table
|
39
|
+
(e.g. Org). The naming convention is that the plural refers to the
|
40
|
+
table and the singular refers to the row. These are tightly coupled,
|
41
|
+
and generally if one exists the other will too.
|
42
|
+
|
43
|
+
The table class (e.g. Orgs) provides access to the raw Sequel
|
44
|
+
objects. There are several constants in the REPL containing
|
45
|
+
pre-initialized instances of the commonly accessed table classes,
|
46
|
+
including ORGS, USERS, ASSOCIATIONS, and INVITES.
|
47
|
+
|
48
|
+
#### Standard accessors
|
49
|
+
|
50
|
+
Each of these have accessors to search by various columns. These use the naming pattern #by\_XXXX, where XXX is the column name in the database. For example ORGS.by\_name('ponyville') searches for the org named 'ponyville'. The return value from this accessor is a new instance of the object that can be further refined. In many cases aliases have been added to hide naming quirks. For example groups use the 'groupname' column, but they can also be accessed using the #by\_name function.
|
51
|
+
|
52
|
+
The REPL supports method completion, so the list of supported filters can be found by typing `ORGS.by_` and hitting the tab key.
|
53
|
+
|
54
|
+
To get a list of all objects selected use the #all method. To list the names of the objects use the #list
|
55
|
+
method:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
fixie:0 > ORGS.list
|
59
|
+
["acme", "ponyville", "wonderbolts"]
|
60
|
+
fixie:0 > ORGS.all
|
61
|
+
[#<Fixie::Sql::Org:0x00000003886fa0 @data=#< @values={:id=>"ca0542c21119786fd4d2ddeb5c920ecf", :authz_id=>"baefe78d2fdab7d31fce7f4bdd6feda8", :name=>"ponyville", :full_name=>"ponyville", :assigned_at=>2015-02-05 03:06:33 UTC, :last_updated_by=>"9f6f823739fe6417b1c247ca0d2afdfc", :created_at=>2015-02-05 03:06:33 UTC, :updated_at=>2015-02-05 03:06:33 UTC}>>, #<Fixie::Sql::Org:0x00000003886f50 @data=#< @values={:id=>"2742f6f01ae95aa5998fd7ad94e0d383", :authz_id=>"52064f4a67a2b6c0243051e9f855699a", :name=>"wonderbolts", :full_name=>"wonderbolts", :assigned_at=>2015-02-05 03:07:05 UTC, :last_updated_by=>"9f6f823739fe6417b1c247ca0d2afdfc", :created_at=>2015-02-05 03:07:05 UTC, :updated_at=>2015-02-05 03:07:05 UTC}>>, #<Fixie::Sql::Org:0x00000003886f28 @data=#< @values={:id=>"0434803f600f1688707081921cf92721", :authz_id=>"b9a9dee90b6c2ab31cf4350aeba59460", :name=>"acme", :full_name=>"acme", :assigned_at=>2015-02-05 03:07:32 UTC, :last_updated_by=>"9f6f823739fe6417b1c247ca0d2afdfc", :created_at=>2015-02-05 03:07:32 UTC, :updated_at=>2015-02-05 03:07:32 UTC}>>]
|
62
|
+
```
|
63
|
+
|
64
|
+
The #all and #list functions have protection against accidentally grabbing the entire table; if too many
|
65
|
+
results are included (currently 10), it returns `:too_many_results` instead. Providing a parameter to the #all
|
66
|
+
and #list function adjusts the limit.
|
67
|
+
|
68
|
+
Any object that has a well defined 'name' has the index ('[]') accessor provided; this takes a string and
|
69
|
+
returns a single exact match for it if it exists.
|
70
|
+
|
71
|
+
#### Predefined objects
|
72
|
+
* USERS
|
73
|
+
|
74
|
+
This allows access to the users table in sql.
|
75
|
+
|
76
|
+
To get the user named 'rainbowdash'
|
77
|
+
```ruby
|
78
|
+
> u = USERS['rainbowdash']
|
79
|
+
#<Fixie::Sql::User:0x00000002afea18 @data=#< @values={:id=>"0000000000004d3eac4cc85b2bdddd0f", :authz_id=>"070dc1cd727a6b71e48d5e16f8d7b137", :username=>"rainbowdash", :email=>"rainbowdash@ponyville.com", :pubkey_version=>0, :public_key=>"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0ZeWeIuU+rO2m1Pe8Nk\n7kzkqmk+CbaP8CVc0OlPZZITgoW2NEseCg1N3FVrCGIIY8vhDkyPST7ZKNva/hOo\nltC8inN695wRchQ1EDpVityL7EIuu7haXBib2WA2HQezlRWKMdrMGGRq0bMa3lD4\nV/YfEXSBtkE8W7QaanbtpgipWC1VGorj0MLR+++JYGd9kqGp49DiC7FH+DChE6pj\nRD9d25/chclD+svZy7RW0s2Q0/H/qRjhOdHoBGljJohVF64CsfqhDCr02zytbKDy\n6sOFjFneSqDZhlx81uVtQ0l+H+0bx77zbwLtp/WjpUFjw/yA8V92/WCjvwMTUaRN\nxQIDAQAB\n-----END PUBLIC KEY-----\n\n", :serialized_object=>"{\"display_name\":\"rainbowdash pony\",\"first_name\":\"rainbowdash\",\"last_name\":\"pony\",\"middle_name\":\"\"}", :last_updated_by=>"c8bd48b83f61031c29ab4ff5168fccd2", :created_at=>2014-10-31 16:59:37 UTC, :updated_at=>2014-10-31 16:59:37 UTC, :external_authentication_uid=>nil, :recovery_authentication_enabled=>false, :admin=>false, :hashed_password=>"$2a$12$FZMrxfVxWLpj8xPiBXG6SO2YxqGMp3zAj7I4w7cr50y1VbCbgIrUe", :salt=>"$2a$12$FZMrxfVxWLpj8xPiBXG6SO", :hash_type=>"bcrypt"}>>
|
80
|
+
```
|
81
|
+
|
82
|
+
|
83
|
+
To see just the name of that user:
|
84
|
+
```ruby
|
85
|
+
> u.name
|
86
|
+
"rainbowdash"
|
87
|
+
```
|
88
|
+
|
89
|
+
To find all users with ponyville in their name:
|
90
|
+
```ruby
|
91
|
+
> USERS.by_email(/ponyville/)
|
92
|
+
#<Fixie::Sql::Users:0x00000003514200 @inner=#<Sequel::Postgres::Dataset: "SELECT * FROM \"users\" WHERE (\"email\" ~ 'ponyville')">>
|
93
|
+
```
|
94
|
+
|
95
|
+
Note this returns a users table object which can be refined
|
96
|
+
further. To process the list of users selected, use the #all method:
|
97
|
+
```ruby
|
98
|
+
> USERS.by_email(/ponyville/).all.map {|x| x.name }
|
99
|
+
["rainbowdash", "fluttershy", "applejack", "pinkiepie", "twilightsparkle", "rarity"]
|
100
|
+
```
|
101
|
+
|
102
|
+
To further refine the set of objects further selectors can be applied:
|
103
|
+
```ruby
|
104
|
+
fixie:0 > USERS.by_email(/ponyville/).by_username(/apple/).all.first.name
|
105
|
+
"applejack"
|
106
|
+
```
|
107
|
+
|
108
|
+
The #all method has a hidden limit (which may be changed in future versions). It has takes a paramenter max\_count (defaults to 10). If it will return more than max\_count elements it returns :too\_many\_results instead; this is to prevent filling the screen or slammming the database by accident.
|
109
|
+
```ruby
|
110
|
+
fixie:0 > USERS.all
|
111
|
+
:too_many_results
|
112
|
+
```
|
113
|
+
* ORGS
|
114
|
+
|
115
|
+
ORGS work very similarly to USERS, but the org object return also adds accessors for org scoped objects such as nodes, roles, groups, containers, etc.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
fixie:0 > ORGS['ponyville'].full_name
|
119
|
+
"ponyville"
|
120
|
+
|
121
|
+
fixie:0 > ORGS['ponyville'].groups.all.map {|x| x.name}
|
122
|
+
["admins", "billing-admins", "clients", "0000000000004d3eac4cc85b2bdddd0f", "000000000000506ccf528a2844e81838", "000000000000808da6731453e12eb2bb", "000000000000dfccddd011ce219caaf0", "00000000000036639a19f27527b29a3e", "000000000000224a1c0e395b112c1d20", "users"]
|
123
|
+
```
|
124
|
+
|
125
|
+
* ASSOCS
|
126
|
+
* INVITES
|
127
|
+
* GLOBAL\_GROUPS
|
128
|
+
* GLOBAL\_CONTAINERS
|
129
|
+
|
130
|
+
Altering ACLs and Groups
|
131
|
+
-----------
|
132
|
+
|
133
|
+
|
134
|
+
#### Editing ACLs
|
135
|
+
|
136
|
+
The objects returned by the above selectors have accessors to allow editing of acl and group membership.
|
137
|
+
|
138
|
+
ACLs can be viewed for any object
|
139
|
+
```ruby
|
140
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].acl
|
141
|
+
{"create"=>{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"]]}, "read"=>{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"]]}, "update"=>{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"]]}, "delete"=>{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"]]}, "grant"=>{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"]]}}
|
142
|
+
```
|
143
|
+
|
144
|
+
Individual ACEs can be viewed
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace(:read)
|
148
|
+
{"actors"=>[[:global, "pivotal"], [:global, "fluttershy"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"]]}
|
149
|
+
```
|
150
|
+
|
151
|
+
Users and groups can be added to an ACE. The APIs are 'magic' in the sense that they can take an object and figure out if it is an actor or group and add it appropriately.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_add(:read, USERS['fluttershy'])
|
155
|
+
{}
|
156
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_add(:read, GLOBAL_GROUPS['ponyville_global_admins'])
|
157
|
+
{}
|
158
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace(:read)
|
159
|
+
{"actors"=>[[:global, "pivotal"], [:global, "fluttershy"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"], ["unknown-00000000000000000000000000000000", "ponyville_global_admins"]]}
|
160
|
+
```
|
161
|
+
|
162
|
+
And removed:
|
163
|
+
```ruby
|
164
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_delete(:read, GLOBAL_GROUPS['ponyville_global_admins'])
|
165
|
+
{}
|
166
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace(:read)
|
167
|
+
{"actors"=>[[:global, "pivotal"], [:global, "fluttershy"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"]]}
|
168
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_delete(:read, USERS['fluttershy'])
|
169
|
+
{}
|
170
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace(:read)
|
171
|
+
{"actors"=>[[:global, "pivotal"]], "groups"=>[["ponyville", "admins"], ["ponyville", "users"]]}
|
172
|
+
```
|
173
|
+
|
174
|
+
The ace\_add and ace\_delete functions take the symbols :create, :read, :update, :delete and :grant in
|
175
|
+
the action field. The user can also provide an array of those symbols for bulk operations, or
|
176
|
+
specify :all to edit all of the actions.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_add(:all, USERS['pivotal'])
|
180
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].ace_add([:read,:update], USERS['fluttershy'])
|
181
|
+
```
|
182
|
+
|
183
|
+
|
184
|
+
##### Copying ACLs
|
185
|
+
|
186
|
+
Sometimes it is useful to copy permisons from one object to another. For example, if an object has
|
187
|
+
had a catastrophic permission edit, you'd like to at least restore the permissions it would have
|
188
|
+
inherited from the container. This command *adds* permissions from another object, but does not
|
189
|
+
remove any permisions already there.
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
fixie:0 > clients_container = ORGS['ponyville'].containers['clients']
|
193
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].acl_add_from_object(clients_container)
|
194
|
+
```
|
195
|
+
|
196
|
+
##### Raw access
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
There are also _raw versions of these functions that work on the raw authz ids
|
201
|
+
```ruby
|
202
|
+
fixie:0 > ORGS['ponyville'].clients['ponyville-validator'].acl_raw
|
203
|
+
{"create"=>{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>["ca0a8cabaafaae658edd298ddd4266cd"]}, "read"=>{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>["ca0a8cabaafaae658edd298ddd4266cd", "690063dd87f110eabfa5ba387b8e280f"]}, "update"=>{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>["ca0a8cabaafaae658edd298ddd4266cd"]}, "delete"=>{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>["ca0a8cabaafaae658edd298ddd4266cd", "690063dd87f110eabfa5ba387b8e280f"]}, "grant"=>{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>["ca0a8cabaafaae658edd298ddd4266cd"]}}
|
204
|
+
```
|
205
|
+
|
206
|
+
#### Editing groups
|
207
|
+
|
208
|
+
Groups can be viewed:
|
209
|
+
```ruby
|
210
|
+
fixie:0 > ORGS['ponyville'].groups['admins'].group
|
211
|
+
{"actors"=>[[:global, "pivotal"]], "groups"=>[]}
|
212
|
+
```
|
213
|
+
|
214
|
+
Members can be added/removed from groups:
|
215
|
+
```ruby
|
216
|
+
fixie:0 > ORGS['ponyville'].groups['admins'].group_add(USERS['fluttershy'])
|
217
|
+
{}
|
218
|
+
fixie:0 > ORGS['ponyville'].groups['admins'].group_delete(USERS['fluttershy'])
|
219
|
+
{}
|
220
|
+
```
|
221
|
+
|
222
|
+
Again there are raw functions that take raw authz ids.
|
223
|
+
```ruby
|
224
|
+
fixie:0 > ORGS['ponyville'].groups['admins'].group_raw
|
225
|
+
{"actors"=>["c8bd48b83f61031c29ab4ff5168fccd2"], "groups"=>[]}
|
226
|
+
```
|
227
|
+
|
228
|
+
|