chef_fixie 0.3.0 → 1.0.2

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 (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