terraorg 0.3.0 → 0.5.4

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