chef_fixie 0.3.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/bin/chef_fixie +1 -1
  3. data/doc/BulkFixup.md +1 -1
  4. data/doc/CommonTasks.md +14 -3
  5. data/lib/chef_fixie.rb +7 -7
  6. data/lib/chef_fixie/authz_mapper.rb +26 -28
  7. data/lib/chef_fixie/authz_objects.rb +44 -41
  8. data/lib/chef_fixie/bulk_edit_permissions.rb +24 -20
  9. data/lib/chef_fixie/check_org_associations.rb +56 -58
  10. data/lib/chef_fixie/config.rb +58 -24
  11. data/lib/chef_fixie/console.rb +15 -10
  12. data/lib/chef_fixie/context.rb +2 -4
  13. data/lib/chef_fixie/sql.rb +12 -12
  14. data/lib/chef_fixie/sql_objects.rb +49 -38
  15. data/lib/chef_fixie/utility_helpers.rb +13 -9
  16. data/lib/chef_fixie/version.rb +1 -1
  17. data/spec/chef_fixie/acl_spec.rb +23 -25
  18. data/spec/chef_fixie/assoc_invite_spec.rb +5 -8
  19. data/spec/chef_fixie/check_org_associations_spec.rb +14 -17
  20. data/spec/chef_fixie/groups_spec.rb +7 -11
  21. data/spec/chef_fixie/org_spec.rb +4 -5
  22. data/spec/chef_fixie/orgs_spec.rb +6 -9
  23. data/spec/spec_helper.rb +5 -6
  24. metadata +18 -84
  25. data/bin/bundler +0 -16
  26. data/bin/chef-apply +0 -16
  27. data/bin/chef-client +0 -16
  28. data/bin/chef-shell +0 -16
  29. data/bin/chef-solo +0 -16
  30. data/bin/chef-zero +0 -16
  31. data/bin/coderay +0 -16
  32. data/bin/edit_json.rb +0 -16
  33. data/bin/erubis +0 -16
  34. data/bin/ffi-yajl-bench +0 -16
  35. data/bin/fixie~ +0 -231
  36. data/bin/htmldiff +0 -16
  37. data/bin/knife +0 -16
  38. data/bin/ldiff +0 -16
  39. data/bin/net-dhcp +0 -16
  40. data/bin/ohai +0 -16
  41. data/bin/prettify_json.rb +0 -16
  42. data/bin/pry +0 -16
  43. data/bin/rackup +0 -16
  44. data/bin/rake +0 -16
  45. data/bin/rdoc +0 -16
  46. data/bin/restclient +0 -16
  47. data/bin/ri +0 -16
  48. data/bin/rspec +0 -16
  49. data/bin/s3sh +0 -16
  50. data/bin/sequel +0 -16
  51. data/bin/serverspec-init +0 -16
  52. data/doc/AccessingSQL.md~ +0 -32
  53. data/doc/BulkFixup.md~ +0 -28
  54. data/doc/CommonTasks.md~ +0 -0
  55. data/doc/GETTING_STARTED.md~ +0 -6
  56. data/spec/chef_fixie/assoc_invite_spec.rb~ +0 -26
  57. data/spec/chef_fixie/check_org_associations_spec.rb~ +0 -34
  58. data/spec/chef_fixie/org_spec.rb~ +0 -53
@@ -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 'ffi_yajl'
20
- require 'uuidtools'
21
- require 'sequel'
19
+ require "ffi_yajl"
20
+ require "uuidtools"
21
+ require "sequel"
22
22
 
23
- require_relative 'config'
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 'pp'
21
- require 'sequel'
20
+ require "pp"
21
+ require "sequel"
22
22
 
23
- require_relative 'config'
24
- require_relative 'authz_objects'
25
- require_relative 'authz_mapper'
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('::')[-1]
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 = self.to_name(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 = self.to_name(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 = self.to_name(name)
70
+ name = to_name(name)
69
71
  name.to_s.singularize
70
72
  end
73
+
71
74
  def self.plural(name)
72
- name = self.to_name(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
- self.class_eval(fundef)
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
- self.class_eval(fundef)
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
- self.ro_access(i)
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
- self.std_timestamp
116
+ std_timestamp
111
117
  [:authz_id, :last_updated_by].each do |i|
112
- self.ro_access(i)
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 self.respond_to?(:authz_delete)
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
- self.class_eval(fundef)
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
@@ -145,16 +152,20 @@ module ChefFixie
145
152
  def global_admins
146
153
  name = self.name
147
154
  global_admins_name = "#{name}_global_admins"
148
- ChefFixie::Sql::Groups.new["#{name}_global_admins"]
155
+ read_access_name = "#{name}_read_access_group"
156
+ ChefFixie::Sql::Groups.new[global_admins_name] || \
157
+ ChefFixie::Sql::Groups.new[read_access_name]
149
158
  end
150
159
 
160
+ alias read_access_group global_admins
161
+
151
162
  # Iterators for objects in authz; using containers to enumerate things
152
163
  # It might be better to metaprogram this up instead,
153
164
  #
154
165
  # TODO Write some tests to validate that this stuff
155
166
  # works, since it depends on a lot of name magic...
156
167
 
157
- NAME_FIXUP = {"data" => "data_bags", "sandboxes" => nil}
168
+ NAME_FIXUP = { "data" => "data_bags", "sandboxes" => nil }
158
169
  def objects_by_container_type(container)
159
170
  name = NAME_FIXUP.has_key?(container) ? NAME_FIXUP[container] : container
160
171
  return [] if name.nil?
@@ -172,7 +183,7 @@ module ChefFixie
172
183
  yield objects
173
184
  end
174
185
  end
175
- return
186
+ nil
176
187
  end
177
188
 
178
189
  def each_authz_object
@@ -181,7 +192,7 @@ module ChefFixie
181
192
  yield object
182
193
  end
183
194
  end
184
- return
195
+ nil
185
196
  end
186
197
 
187
198
  scoped_type :container, :group, :client,
@@ -253,7 +264,6 @@ module ChefFixie
253
264
  # org_migration_state_id_seq policy_revisions
254
265
  # policy_revisions_policy_groups_association sandboxed_checksums
255
266
 
256
-
257
267
  class CookbookArtifact < SqlObject
258
268
  include AuthzObjectMixin
259
269
  def initialize(data)
@@ -338,31 +348,33 @@ module ChefFixie
338
348
  def get_table
339
349
  :unknown_table
340
350
  end
351
+
341
352
  def mk_element(x)
342
353
  x
343
354
  end
344
355
 
345
356
  def initialize(tablespec = nil)
346
357
  ChefFixie::Sql.default_connection
347
- @inner = tablespec || Sequel::Model(self.get_table)
358
+ @inner = tablespec || Sequel::Model(get_table)
348
359
  end
360
+
349
361
  def inner
350
362
  # Make sure we have init
351
363
  @inner
352
364
  end
353
365
 
354
366
  def filter_core(field, exp)
355
- self.class.new(inner.filter(field=>exp))
367
+ self.class.new(inner.filter(field => exp))
356
368
  end
357
369
 
358
- def all(max_count=:default)
370
+ def all(max_count = :default)
359
371
  if max_count == :default
360
372
  max_count = ChefFixie::Sql::SqlTable.max_count_default
361
373
  end
362
374
  if max_count != :all
363
- return :too_many_results if (inner.count > max_count)
375
+ return :too_many_results if inner.count > max_count
364
376
  end
365
- elements = inner.all.map {|org| mk_element(org) }
377
+ elements = inner.all.map { |org| mk_element(org) }
366
378
  end
367
379
 
368
380
  #
@@ -371,7 +383,7 @@ module ChefFixie
371
383
  # https://stackoverflow.com/questions/9658724/ruby-metaprogramming-class-eval/9658775#9658775
372
384
  def self.primary(arg)
373
385
  name = :"by_#{arg}"
374
- self.class_eval("def [](arg); #{name}(arg).all(1).first; end")
386
+ class_eval("def [](arg); #{name}(arg).all(1).first; end")
375
387
 
376
388
  listfun = <<EOLF
377
389
  def list(max_count=:default)
@@ -383,26 +395,27 @@ def list(max_count=:default)
383
395
  end
384
396
  end
385
397
  EOLF
386
- self.class_eval(listfun)
398
+ class_eval(listfun)
387
399
  end
388
400
 
389
401
  def self.filter_by(*args)
390
402
  args.each do |field|
391
403
  name = "by_#{field}"
392
404
  fundef = "def #{name}(exp); filter_core(:#{field},exp); end"
393
- self.class_eval(fundef)
405
+ class_eval(fundef)
394
406
  end
395
407
  end
396
408
 
397
409
  def self.table(name)
398
410
  fundef = "def get_table; :#{name}; end"
399
- self.class_eval(fundef)
411
+ class_eval(fundef)
400
412
  end
413
+
401
414
  # doesn't work yet
402
415
  # element Org in class Orgs will fail because it can't find Org (undefined)
403
416
  def self.element(name)
404
417
  fundef = "ElementType = name; def mk_element(x); #{name}.new(x); end"
405
- self.class_eval(fundef)
418
+ class_eval(fundef)
406
419
  end
407
420
  end
408
421
 
@@ -414,7 +427,7 @@ EOLF
414
427
  primary :name
415
428
  filter_by :name, :id, :full_name, :authz_id
416
429
 
417
- GlobalOrg = "0"*32
430
+ GlobalOrg = "0" * 32
418
431
 
419
432
  def self.org_guid_to_name(guid)
420
433
  "global" if guid == GlobalOrg
@@ -435,7 +448,7 @@ EOLF
435
448
 
436
449
  def by_org_id_user_id(org_id, user_id)
437
450
  # db table constraint guarantees that this is unique
438
- 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
439
452
  end
440
453
 
441
454
  end
@@ -445,7 +458,7 @@ EOLF
445
458
 
446
459
  def by_org_id_user_id(org_id, user_id)
447
460
  # db table constraint guarantees that this is unique
448
- 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
449
462
  end
450
463
  end
451
464
  class Users < SqlTable
@@ -547,7 +560,7 @@ EOLF
547
560
  filter_by :name, :id, :org_id, :authz_id
548
561
  end
549
562
 
550
- class Roles < SqlTable
563
+ class Roles < SqlTable
551
564
  table :roles
552
565
  element Sql::Role
553
566
  register_authz :role, :object
@@ -556,7 +569,5 @@ EOLF
556
569
  filter_by :name, :id, :org_id, :authz_id, :last_updated_by
557
570
  end
558
571
 
559
-
560
-
561
572
  end
562
573
  end
@@ -18,42 +18,46 @@
18
18
  # Author: Mark Anderson <mark@chef.io>
19
19
  #
20
20
 
21
- require_relative 'config'
22
- require_relative 'authz_objects'
23
- require_relative 'authz_mapper'
21
+ require_relative "config"
22
+ require_relative "authz_objects"
23
+ require_relative "authz_mapper"
24
24
 
25
25
  module ChefFixie
26
26
  module UtilityHelpers
27
27
  def self.orgs
28
28
  @orgs ||= ChefFixie::Sql::Orgs.new
29
29
  end
30
+
30
31
  def self.users
31
32
  @users ||= ChefFixie::Sql::Users.new
32
33
  end
34
+
33
35
  def self.assocs
34
36
  @assocs ||= ChefFixie::Sql::Associations.new
35
37
  end
38
+
36
39
  def self.invites
37
40
  invites ||= ChefFixie::Sql::Invites.new
38
41
  end
39
42
 
40
43
  def self.make_user(user)
41
44
  if user.is_a?(String)
42
- return users[user]
45
+ users[user]
43
46
  elsif user.is_a?(ChefFixie::Sql::User)
44
- return user
47
+ user
45
48
  else
46
49
  raise Exception "Expected a user, got a #{user.class}"
47
50
  end
48
- end
51
+ end
52
+
49
53
  def self.make_org(org)
50
54
  if org.is_a?(String)
51
- return orgs[org]
55
+ orgs[org]
52
56
  elsif org.is_a?(ChefFixie::Sql::Org)
53
- return org
57
+ org
54
58
  else
55
59
  raise Exception "Expected an org, got a #{org.class}"
56
60
  end
57
- end
61
+ end
58
62
  end
59
63
  end
@@ -1,3 +1,3 @@
1
1
  module ChefFixie
2
- VERSION = "0.3.0"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -1,46 +1,45 @@
1
1
 
2
- require 'rspec'
2
+ require "rspec"
3
3
  require "spec_helper"
4
- require 'chef_fixie'
5
- require 'chef_fixie/config'
4
+ require "chef_fixie"
5
+ require "chef_fixie/config"
6
6
 
7
7
  RSpec.describe ChefFixie::Sql::Orgs, "ACL access" do
8
- let (:test_org_name) { "ponyville"}
8
+ let (:test_org_name) { "ponyville" }
9
9
  let (:orgs) { ChefFixie::Sql::Orgs.new }
10
10
  let (:users) { ChefFixie::Sql::Users.new }
11
11
  let (:test_org) { orgs[test_org_name] }
12
12
 
13
13
  # TODO this should use a freshly created object and purge it afterwords.
14
14
  # But we need to write the create object feature still
15
-
15
+
16
16
  context "Fetch acl for actor (client)" do
17
17
  let (:testclient) { test_org.clients.all.first }
18
- let (:testuser) { users['spitfire'] }
19
- let (:pivotal) { users['pivotal'] }
18
+ let (:testuser) { users["spitfire"] }
19
+ let (:pivotal) { users["pivotal"] }
20
20
  let (:client_container) { test_org.containers["clients"] }
21
-
21
+
22
22
  it "We can fetch the acl" do
23
23
  acl = testclient.acl
24
- expect(acl.keys).to include(* %w(create read update delete grant))
24
+ expect(acl.keys).to include(* %w{create read update delete grant})
25
25
  end
26
26
 
27
27
  it "we can add a user to an ace" do
28
- # This requires either a temp object or good cleanup
28
+ # This requires either a temp object or good cleanup
29
29
  # acl = testclient.acl
30
30
  # expect(acl["read"]["actors"].not_to include("wonderbolts")
31
-
31
+
32
32
  testclient.ace_add(:read, testuser)
33
33
 
34
34
  acl = testclient.acl
35
35
  expect(acl["read"]["actors"]).to include([:global, testuser.name])
36
36
  end
37
-
37
+
38
38
  it "we can add then delete a user from an ace" do
39
39
  testclient.ace_add(:read, testuser)
40
40
  acl = testclient.acl
41
41
  expect(acl["read"]["actors"]).to include([:global, testuser.name])
42
42
 
43
-
44
43
  testclient.ace_delete(:read, testuser)
45
44
 
46
45
  acl = testclient.acl
@@ -49,26 +48,26 @@ RSpec.describe ChefFixie::Sql::Orgs, "ACL access" do
49
48
 
50
49
  it "we can copy users from another acl" do
51
50
  testclient.ace_delete(:all, pivotal)
52
-
51
+
53
52
  testclient.acl_add_from_object(client_container)
54
53
 
55
54
  acl = testclient.acl
56
- %w(create read update delete grant).each do |action|
55
+ %w{create read update delete grant}.each do |action|
57
56
  expect(acl[action]["actors"]).to include([:global, pivotal.name])
58
57
  end
59
58
  end
60
-
59
+
61
60
  end
62
61
 
63
62
  context "ACE Membership" do
64
-
65
- let (:admingroup) { test_org.groups['admins'] }
66
- let (:testobject) { test_org.groups['admins'] }
67
- let (:notadmingroup) { test_org.groups['clients'] }
68
- let (:adminuser) { users['rainbowdash'] }
69
- let (:notadminuser) { users['mary'] }
70
- let (:pivotal) { users['pivotal'] }
71
-
63
+
64
+ let (:admingroup) { test_org.groups["admins"] }
65
+ let (:testobject) { test_org.groups["admins"] }
66
+ let (:notadmingroup) { test_org.groups["clients"] }
67
+ let (:adminuser) { users["rainbowdash"] }
68
+ let (:notadminuser) { users["mary"] }
69
+ let (:pivotal) { users["pivotal"] }
70
+
72
71
  it "Privileged users and groups are part of the read ACE" do
73
72
  expect(testobject.ace_member?(:read, admingroup)).to be true
74
73
  expect(testobject.ace_member?(:read, pivotal)).to be true
@@ -79,5 +78,4 @@ RSpec.describe ChefFixie::Sql::Orgs, "ACL access" do
79
78
  end
80
79
  end
81
80
 
82
-
83
81
  end