terraorg 0.1.0 → 0.2.0

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: 9dcc3e713e1ec4a3166adfd99ecb9cccb52efd37f489fc18ff2393be0b79ac1a
4
- data.tar.gz: 0d12305ad0d7f2aa129336010f719f0d1361c0d28b2fa9466c2c1205d280830b
3
+ metadata.gz: 7bd7aab93499335ed6575acc6c9e1df72dbac83e57b1086703ac950b2d440107
4
+ data.tar.gz: 4feba8047e97d182a3187d94cacb9fd229811499fe7195afc62550482dc7a3de
5
5
  SHA512:
6
- metadata.gz: 19df8bcc655abfe6eb89a7d5e8d50d7f76298a492b14cb2f37369b17b2f396822897d264d6f861f215faabd0e74af0dc72a23756cac1e319c34d36a60c915783
7
- data.tar.gz: c3b93acbeaa7f18f6f64c4343944649acf2630a99823b53fce3789c20fb1fa8a5be8bebf9159c2a48ae39eb96b5d4af1c669b23d879087a38104f36d330aeb09
6
+ metadata.gz: 168ba8345625402fe6de06dbba2ab30b7223127a2dfed994cf8fbba94beb977bf9d82efc35c88e71bc62d1b5c0f1580d1f843408c9bedd91be8e4f3fd318bb5f
7
+ data.tar.gz: 9f600fa6d33aa1de8db082826122f3bafc788d382ccd564ccd19904a5bc1a077f6520944db3c3fdc3621a633e240a1a59ceefd9ecd98582c092c9855193ba9d7
@@ -15,7 +15,8 @@
15
15
  require 'terraorg/model/util'
16
16
 
17
17
  class Org
18
- MAX_SQUADS_PER_PERSON = 2
18
+ MAX_MEMBER_SQUADS_PER_PERSON = 1
19
+ MAX_ASSOCIATE_SQUADS_PER_PERSON = 3
19
20
  SCHEMA_VERSION = 'v1'.freeze
20
21
 
21
22
  def initialize(parsed_data, platoons, squads, people, gsuite_domain)
@@ -81,17 +82,31 @@ class Org
81
82
  raise "Squads are part of more than one platoon: #{more_than_one_platoon}"
82
83
  end
83
84
 
84
- # Validate that a squad member belongs to at most two squads in the entire org
85
+ # Validate that a squad member belongs to some maximum number of squads
86
+ # across the entire org. A person can be an associate of other squads
87
+ # at a different count. See top of file for defined limits.
85
88
  squad_count = {}
86
89
  all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:members).flatten.each do |member|
87
90
  squad_count[member.id] = squad_count.fetch(member.id, 0) + 1
88
91
  end
89
92
  more_than_max_squads = squad_count.select do |member, count|
90
- count > MAX_SQUADS_PER_PERSON
93
+ count > MAX_MEMBER_SQUADS_PER_PERSON
91
94
  end
92
95
  if !more_than_max_squads.empty?
93
- # TODO(joshk): Enforce after consulting with Sean
94
- $stderr.puts "WARNING: Members are part of more than #{MAX_SQUADS_PER_PERSON} squads: #{more_than_max_squads}"
96
+ # TODO(joshk): Enforce after April 17th
97
+ $stderr.puts "WARNING: Members are part of more than #{MAX_MEMBER_SQUADS_PER_PERSON} squads: #{more_than_max_squads}"
98
+ end
99
+
100
+ associate_count = {}
101
+ all_squads.map(&:teams).flatten.map(&:values).flatten.map(&:associates).flatten.each do |assoc|
102
+ associate_count[assoc.id] = associate_count.fetch(assoc.id, 0) + 1
103
+ end
104
+ more_than_max_squads = associate_count.select do |_, count|
105
+ count > MAX_ASSOCIATE_SQUADS_PER_PERSON
106
+ end
107
+ if !more_than_max_squads.empty?
108
+ # TODO(joshk): Enforce after April 17th
109
+ $stderr.puts "WARNING: People associated with more than #{MAX_ASSOCIATE_SQUADS_PER_PERSON} squads: #{more_than_max_squads}"
95
110
  end
96
111
 
97
112
  # Validate that a squad member is not also an org exception
@@ -99,9 +99,9 @@ EOF
99
99
  # - Sort the squad ids lexically
100
100
  # - Sort the exceptions lexically
101
101
  def to_h
102
- obj = { 'id' => @id, 'name' => @name, 'manager' => @manager.id, 'squads' => @member_squads.map(&:id) }
102
+ obj = { 'id' => @id, 'name' => @name, 'manager' => @manager.id, 'squads' => @member_squads.map(&:id).sort }
103
103
  unless @member_exceptions.empty?
104
- obj['exceptions'] = @member_exceptions.map(&:id)
104
+ obj['exceptions'] = @member_exceptions.map(&:id).sort
105
105
  end
106
106
  unless @metadata.empty?
107
107
  obj['metadata'] = @metadata
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'countries'
16
+
15
17
  require 'terraorg/model/people'
16
18
  require 'terraorg/model/util'
17
19
 
@@ -19,23 +21,54 @@ class Squad
19
21
  attr_accessor :id, :name, :metadata, :teams
20
22
 
21
23
  class Team
22
- attr_accessor :location, :members
24
+ attr_accessor :location, :members, :associates
23
25
 
24
26
  def initialize(parsed_data, people)
25
- @location = parsed_data.fetch('location')
27
+ location = parsed_data.fetch('location')
28
+ country = ISO3166::Country.new(location)
29
+ raise "Location is invalid: #{location}" unless country
30
+ @location = country.alpha2
26
31
  @members = parsed_data.fetch('members', []).map do |n|
27
32
  people.get_or_create!(n)
28
33
  end
34
+ @associates = parsed_data.fetch('associates', []).map do |n|
35
+ people.get_or_create!(n)
36
+ end
37
+ end
38
+
39
+ def validate!
40
+ raise 'Subteam has no full time members' if @members.size == 0
41
+ # location validation done at initialize time
42
+ # associates can be empty
43
+
44
+ # associates and members must have zero intersection
45
+ associate_set = Set.new(@associates.map(&:id))
46
+ member_set = Set.new(@members.map(&:id))
47
+ raise 'A member cannot also be an associate of the same team' if associate_set.intersection(member_set)
29
48
  end
30
49
 
31
50
  # Output a canonical (sorted, formatted) version of this Team.
32
51
  # - Sort the members in each team
52
+ # - Only add an associates field if it's present
33
53
  def to_h
34
- { 'location' => @location, 'members' => @members.map(&:id).sort }
54
+ rv = {
55
+ 'location' => @location,
56
+ 'members' => @members.map(&:id).sort,
57
+ }
58
+
59
+ if @associates.size > 0
60
+ rv['associates'] = @associates.map(&:id).sort
61
+ end
62
+
63
+ rv
64
+ end
65
+
66
+ def everyone
67
+ @associates + @members
35
68
  end
36
69
 
37
70
  def to_md
38
- "**#{@location}**: #{@members.map(&:name).sort.join(', ')}"
71
+ "**#{@location}**: #{@members.map(&:name).sort.join(', ')}, #{@associates.map { |m| "_#{m.name}_" }.sort.join(', ')}"
39
72
  end
40
73
  end
41
74
 
@@ -53,10 +86,18 @@ class Squad
53
86
  @teams = Hash[teams_arr.map { |t| [t.location, t] }]
54
87
  end
55
88
 
56
- def members(location: nil)
89
+ # Everyone including associates on all subteams in the squad.
90
+ def everyone(location: nil)
57
91
  @teams.select { |l, t|
58
92
  location == nil || l == location
59
- }.map { |l, t|
93
+ }.map { |_, t|
94
+ t.everyone
95
+ }.flatten
96
+ end
97
+
98
+ # Full-time members of all subteams in this squad
99
+ def members
100
+ @teams.map { |_, t|
60
101
  t.members
61
102
  }.flatten
62
103
  end
@@ -64,11 +105,11 @@ class Squad
64
105
  def get_acl_groups(org_id)
65
106
  # each geographically located subteam
66
107
  groups = Hash[@teams.map { |location, team|
67
- [unique_name(org_id, location), {'name' => "#{@name} squad members based in #{location}", 'members' => team.members}]
108
+ [unique_name(org_id, location), {'name' => "#{@name} squad members based in #{location}", 'members' => team.everyone}]
68
109
  }]
69
110
 
70
111
  # combination of all subteams
71
- groups[unique_name(org_id, nil)] = {'name' => "#{@name} squad worldwide members", 'members' => members}
112
+ groups[unique_name(org_id, nil)] = {'name' => "#{@name} squad worldwide members", 'members' => everyone}
72
113
 
73
114
  groups
74
115
  end
@@ -82,7 +123,7 @@ class Squad
82
123
  end
83
124
 
84
125
  def validate!
85
- raise 'Squad has no members' if members.size == 0
126
+ @teams.each(&:validate!)
86
127
  end
87
128
 
88
129
  def to_md(platoon_name, org_id)
@@ -94,11 +135,6 @@ class Squad
94
135
  sme = @people.get_or_create!(sme).name
95
136
  end
96
137
 
97
- epo = @metadata.fetch('epo', '')
98
- if !epo.empty?
99
- epo = @people.get_or_create!(epo).name
100
- end
101
-
102
138
  manager = @metadata.fetch('manager', '')
103
139
  if !manager.empty?
104
140
  manager = @people.get_or_create!(manager).name
@@ -110,8 +146,8 @@ class Squad
110
146
  if slack
111
147
  slack = "[#{slack}](https://#{@slack_domain}/app_redirect?channel=#{slack.gsub(/^#/, '')})"
112
148
  end
113
- # platoon name, squad name, PM, email list, SME, slack, # people, squad manager, eng product owner, members
114
- "|#{platoon_name}|#{@name}|#{pm}|[#{email}](#{email})|#{sme}|#{slack}|#{members.size}|#{manager}|#{epo}|#{subteam_members}|"
149
+ # platoon name, squad name, PM, email list, SME, slack, # full time members, squad manager, members
150
+ "|#{platoon_name}|#{@name}|#{pm}|[#{email}](#{email})|#{sme}|#{slack}|#{members.size}|#{manager}|#{subteam_members}|"
115
151
  end
116
152
 
117
153
  def generate_tf(org_id)
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Terraorg
16
- VERSION = '0.1.0'
16
+ VERSION = '0.2.0'
17
17
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terraorg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
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-03-30 00:00:00.000000000 Z
11
+ date: 2020-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: countries
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: faraday
15
29
  requirement: !ruby/object:Gem::Requirement