terraorg 0.3.0 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce81d4e08d1d925fbf0cc419b5012725e33190563592d8ad491bf52a39df2920
4
- data.tar.gz: 1854959244ef5576f9c39f3079ae73e7af243f591c972e3f79ecfb9729a87445
3
+ metadata.gz: 9d4bc0b594ccdebdbc4f31ec4825e6ba58ae14d594c5ba583be66110146bb87e
4
+ data.tar.gz: e91277122e80da862872e04377857462d77bde314c79be37e0c9ec223dcc985c
5
5
  SHA512:
6
- metadata.gz: 498d390c6eb73ff5761ccc40e8a0918d8c0e1ec8ac21d2d5862a9d9b0c7da514e574849a853cb9fce4b8516625bcb72ef6bcc39b2de52e80cbf13fef6e62a5a8
7
- data.tar.gz: 72575c047b7565108453002e809fa2c76346e6a8998f04ff52750c065ecb48eb1b9235f0d0a6cd2e967b81292e30a668d91339b9d1bc26e7fc520669a47a750f
6
+ metadata.gz: f3a0ba270dd09ea04cf4f4acf32374110e1563c56c4259dd2f6664dce55dd37330732fd7bfa2ac530638599afd9e8974ce59bbe452af52bf4d434c5593072ed5
7
+ data.tar.gz: 2bc8103395027c04b74483da0bb62779eefa0544b2f3fc54f2f68131a8d2bec5a35043de45835d15e32fed572acc8b353a27f7ae9d045faf6b308d93524f8a29
data/README.md CHANGED
@@ -34,7 +34,9 @@ Based on the org that this tool was originally designed for, orgs are expected
34
34
  to have three levels:
35
35
 
36
36
  * *squads*: the base unit of team-dom, containing people, who may be in
37
- different geographical regions.
37
+ different geographical regions. Teams contain _members_ (full time heads)
38
+ and _associates_ (typically part time floaters.) Any associate of a squad
39
+ must also have a home squad for which they are a full time member.
38
40
  * *platoons*: a unit which contains squads and exceptional people who are
39
41
  members of the platoon, but not part of any squad
40
42
  * *org*: The whole organization, including its manager, any exceptional squads
@@ -45,6 +47,10 @@ The tool generates groups for each granular unit of organization in Okta and G
45
47
  Suite in Terraform. With patching, it could be possible for more organizational
46
48
  systems to be supported.
47
49
 
50
+ ## Diagram
51
+
52
+ ![Diagram of org structure](img/diagram.png)
53
+
48
54
  ## How it works
49
55
 
50
56
  Firstly, take your entire existing organization and define it using the
@@ -120,6 +126,10 @@ information on how to configure the providers.
120
126
  [articulate/terraform-provider-okta]: https://github.com/articulate/terraform-provider-okta
121
127
  [DeviaVir/terraform-provider-gsuite]: https://github.com/DeviaVir/terraform-provider-gsuite
122
128
 
129
+ ## Running tests
130
+ There are a limited number of tests that can be invoked with
131
+ `ruby -I lib test/terraorg/model/org_test.rb `
132
+
123
133
  ## Suggested process
124
134
 
125
135
  At [LiveRamp], a pull request based workflow leveraging [Atlantis] is used to
@@ -32,6 +32,7 @@ ACTIONS = [
32
32
  ].freeze
33
33
 
34
34
  STRICT_VALIDATION = ENV.fetch('TERRAORG_STRICT_VALIDATION', 'true')
35
+ ALLOW_ORPHANED_ASSOCIATES = ENV.fetch('ALLOW_ORPHANED_ASSOCIATES', 'false')
35
36
  SQUADS_FILE = ENV.fetch('TERRAORG_SQUADS', 'squads.json')
36
37
  PLATOONS_FILE = ENV.fetch('TERRAORG_PLATOONS', 'platoons.json')
37
38
  ORG_FILE = ENV.fetch('TERRAORG_ROOT', 'org.json')
@@ -97,7 +98,8 @@ org_data = File.read(ORG_FILE)
97
98
  org = Org.new(JSON.parse(org_data), platoons, squads, people, GSUITE_DOMAIN)
98
99
 
99
100
  strict = (STRICT_VALIDATION == 'true')
100
- org.validate!(strict: strict)
101
+ allow_orphaned_associates = (ALLOW_ORPHANED_ASSOCIATES == 'true')
102
+ org.validate!(strict: strict, allow_orphaned_associates: allow_orphaned_associates)
101
103
 
102
104
  case action
103
105
  when 'generate-squads-md'
@@ -1,4 +1,5 @@
1
1
  # Copyright 2019-2020 LiveRamp Holdings, Inc.
2
+ # Copyright 2020- Joshua Kwan
2
3
  #
3
4
  # Licensed under the Apache License, Version 2.0 (the "License");
4
5
  # you may not use this file except in compliance with the License.
@@ -49,12 +50,12 @@ class Org
49
50
  @squads = squads
50
51
  end
51
52
 
52
- def validate!(strict: true)
53
+ def validate!(strict: true, allow_orphaned_associates: false)
53
54
  failure = false
54
55
 
55
56
  # Do not allow the JSON files to contain any people who have left.
56
57
  unless @people.inactive.empty?
57
- $stderr.puts "ERROR: Users have left the company: #{@people.inactive.map(&:id).join(', ')}"
58
+ $stderr.puts "ERROR: Users have left the company, or are Suspended in Okta: #{@people.inactive.map(&:id).join(', ')}"
58
59
  failure = true
59
60
  end
60
61
 
@@ -97,7 +98,8 @@ class Org
97
98
  # across the entire org. A person can be an associate of other squads
98
99
  # at a different count. See top of file for defined limits.
99
100
  squad_count = {}
100
- all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:members).flatten.each do |member|
101
+ all_members = all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:members).flatten
102
+ all_members.each do |member|
101
103
  squad_count[member.id] = squad_count.fetch(member.id, 0) + 1
102
104
  end
103
105
  more_than_max_squads = squad_count.select do |member, count|
@@ -109,7 +111,8 @@ class Org
109
111
  end
110
112
 
111
113
  associate_count = {}
112
- all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:associates).flatten.each do |assoc|
114
+ all_associates = all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:associates).flatten
115
+ all_associates.each do |assoc|
113
116
  associate_count[assoc.id] = associate_count.fetch(assoc.id, 0) + 1
114
117
  end
115
118
  more_than_max_squads = associate_count.select do |_, count|
@@ -130,6 +133,15 @@ class Org
130
133
  failure = true
131
134
  end
132
135
 
136
+ # Validate that any associate is a member of some squad
137
+ if !allow_orphaned_associates
138
+ associates_but_not_members = Set.new(all_associates.map(&:id)) - Set.new(all_members.map(&:id)) - exceptions
139
+ if !associates_but_not_members.empty?
140
+ $stderr.puts "ERROR: #{associates_but_not_members.to_a} are associates of squads but not members of any squad"
141
+ failure = true
142
+ end
143
+ end
144
+
133
145
  raise "CRITICAL: Validation failed due to at least one error above" if failure && strict
134
146
  end
135
147
 
@@ -193,13 +205,16 @@ class Org
193
205
  md_lines.join("\n")
194
206
  end
195
207
 
196
- def generate_tf
197
- tf = @member_platoons.map { |p| p.generate_tf(@id) }.join("\n")
198
- File.write('auto.platoons.tf', tf)
208
+ def generate_tf_platoons
209
+ @member_platoons.map { |p| p.generate_tf(@id) }.join("\n")
210
+ end
199
211
 
200
- tf = @member_exception_squads.map { |s| s.generate_tf(@id) }.join("\n")
201
- File.write('auto.exception_squads.tf', tf)
212
+ def generate_tf_squads
213
+ @member_exception_squads.map { |s| s.generate_tf(@id) }.join("\n")
214
+ end
202
215
 
216
+ def generate_tf_org
217
+ tf = ''
203
218
  # Roll all platoons and exception squads into the org.
204
219
  roll_up_to_org = \
205
220
  @member_exception_squads.map { |s| s.unique_name(@id, nil) } + \
@@ -239,14 +254,18 @@ EOF
239
254
  all_locations[@manager_location] = all_locations.fetch(@manager_location, Set.new).add(@manager)
240
255
 
241
256
  all_locations.each do |l, m|
257
+ description = "#{@name} organization members based in #{l} (terraorg)"
242
258
  name = "#{unique_name}-#{l.downcase}"
243
259
  tf += <<-EOF
244
260
  resource "okta_group" "#{name}" {
245
261
  name = "#{name}"
246
- description = "#{@name} organization members based in #{l} (terraorg)"
262
+ description = "#{description}"
247
263
  users = #{Util.persons_tf(m)}
248
264
  }
265
+
266
+ #{Util.gsuite_group_tf(name, @gsuite_domain, m, description)}
249
267
  EOF
268
+
250
269
  end
251
270
 
252
271
  # Generate a special GSuite group for all managers (org, platoon, squad
@@ -255,7 +274,17 @@ EOF
255
274
  all_managers = Set.new([@manager] + @platoons.all.map(&:manager) + @squads.all.map(&:manager).select { |m| m })
256
275
  manager_dl = "#{@id}-managers"
257
276
  tf += Util.gsuite_group_tf(manager_dl, @gsuite_domain, all_managers, "All managers of the #{@name} organization (terraorg)")
277
+ tf
278
+ end
279
+
280
+ def generate_tf
281
+ tf = generate_tf_platoons
282
+ File.write('auto.platoons.tf', tf)
283
+
284
+ tf = generate_tf_squads
285
+ File.write('auto.exception_squads.tf', tf)
258
286
 
287
+ tf = generate_tf_org
259
288
  File.write('auto.org.tf', tf)
260
289
  end
261
290
 
@@ -14,8 +14,11 @@
14
14
 
15
15
  require 'faraday'
16
16
 
17
+ # The following statuses are considered ACTIVE by terraorg, which allow PRs to continue and be merged.
18
+ # A DEACTIVATED account status needs to be removed from the repository before merging PRs
19
+
17
20
  class Person
18
- ACTIVE_USER_STATUSES = ['ACTIVE', 'PROVISIONED'].freeze
21
+ ACTIVE_USER_STATUSES = ['ACTIVE', 'PROVISIONED', 'PASSWORD_EXPIRED', 'SUSPENDED'].freeze
19
22
 
20
23
  attr_accessor :id, :name, :okta_id, :email, :status
21
24
 
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Terraorg
16
- VERSION = '0.3.0'
16
+ VERSION = '0.5.4'
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraorg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Kwan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-27 00:00:00.000000000 Z
11
+ date: 2021-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: countries
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.14'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.14'
69
83
  description: Manage an organizational structure with Okta and G-Suite using Terraform
70
84
  email: joshk@triplehelix.org
71
85
  executables:
@@ -104,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
118
  - !ruby/object:Gem::Version
105
119
  version: '0'
106
120
  requirements: []
107
- rubygems_version: 3.0.3
121
+ rubygems_version: 3.0.8
108
122
  signing_key:
109
123
  specification_version: 4
110
124
  summary: terraorg