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 +4 -4
- data/README.md +11 -1
- data/bin/terraorg +3 -1
- data/lib/terraorg/model/org.rb +39 -10
- data/lib/terraorg/model/person.rb +4 -1
- data/lib/terraorg/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4bc0b594ccdebdbc4f31ec4825e6ba58ae14d594c5ba583be66110146bb87e
|
4
|
+
data.tar.gz: e91277122e80da862872e04377857462d77bde314c79be37e0c9ec223dcc985c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+

|
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
|
data/bin/terraorg
CHANGED
@@ -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
|
-
|
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'
|
data/lib/terraorg/model/org.rb
CHANGED
@@ -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
|
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
|
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
|
197
|
-
|
198
|
-
|
208
|
+
def generate_tf_platoons
|
209
|
+
@member_platoons.map { |p| p.generate_tf(@id) }.join("\n")
|
210
|
+
end
|
199
211
|
|
200
|
-
|
201
|
-
|
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 = "#{
|
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
|
|
data/lib/terraorg/version.rb
CHANGED
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.
|
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:
|
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.
|
121
|
+
rubygems_version: 3.0.8
|
108
122
|
signing_key:
|
109
123
|
specification_version: 4
|
110
124
|
summary: terraorg
|