strongdm 1.0.7 → 1.0.13
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 +28 -6
- data/doc/LICENSE.html +1 -11
- data/doc/Object.html +1 -679
- data/doc/README_md.html +32 -19
- data/doc/SDM.html +1 -1
- data/doc/SDM/AKS.html +4 -58
- data/doc/SDM/AKSBasicAuth.html +3 -3
- data/doc/SDM/AKSServiceAccount.html +3 -3
- data/doc/SDM/AccountAttachment.html +2 -2
- data/doc/SDM/AccountAttachmentCreateResponse.html +1 -1
- data/doc/SDM/AccountAttachmentDeleteResponse.html +1 -1
- data/doc/SDM/AccountAttachmentGetResponse.html +1 -1
- data/doc/SDM/AccountAttachments.html +2 -2
- data/doc/SDM/AccountCreateResponse.html +1 -1
- data/doc/SDM/AccountDeleteResponse.html +1 -1
- data/doc/SDM/AccountGetResponse.html +1 -1
- data/doc/SDM/AccountGrant.html +1 -1
- data/doc/SDM/AccountGrantCreateResponse.html +1 -1
- data/doc/SDM/AccountGrantDeleteResponse.html +1 -1
- data/doc/SDM/AccountGrantGetResponse.html +1 -1
- data/doc/SDM/AccountGrants.html +1 -1
- data/doc/SDM/AccountUpdateResponse.html +1 -1
- data/doc/SDM/Accounts.html +9 -9
- data/doc/SDM/AlreadyExistsError.html +1 -1
- data/doc/SDM/AmazonEKS.html +4 -22
- data/doc/SDM/AmazonES.html +3 -3
- data/doc/SDM/Athena.html +3 -3
- data/doc/SDM/AuroraMysql.html +3 -3
- data/doc/SDM/AuroraPostgres.html +3 -3
- data/doc/SDM/AuthenticationError.html +1 -1
- data/doc/SDM/BadRequestError.html +1 -1
- data/doc/SDM/BigQuery.html +3 -3
- data/doc/SDM/Cassandra.html +3 -3
- data/doc/SDM/Citus.html +3 -3
- data/doc/SDM/Client.html +26 -12
- data/doc/SDM/Clustrix.html +3 -3
- data/doc/SDM/Cockroach.html +3 -3
- data/doc/SDM/ControlPanel.html +236 -0
- data/doc/SDM/ControlPanelGetSSHCAPublicKeyResponse.html +267 -0
- data/doc/SDM/CreateResponseMetadata.html +1 -1
- data/doc/SDM/{DB2.html → DB2LUW.html} +7 -7
- data/doc/SDM/DB2i.html +391 -0
- data/doc/SDM/DeadlineExceededError.html +1 -1
- data/doc/SDM/DeleteResponseMetadata.html +1 -1
- data/doc/SDM/Druid.html +3 -3
- data/doc/SDM/DynamoDB.html +3 -3
- data/doc/SDM/Elastic.html +3 -3
- data/doc/SDM/ElasticacheRedis.html +3 -3
- data/doc/SDM/Gateway.html +4 -4
- data/doc/SDM/GetResponseMetadata.html +1 -1
- data/doc/SDM/GoogleGKE.html +4 -40
- data/doc/SDM/Greenplum.html +3 -3
- data/doc/SDM/HTTPAuth.html +3 -3
- data/doc/SDM/HTTPBasicAuth.html +3 -3
- data/doc/SDM/HTTPNoAuth.html +3 -3
- data/doc/SDM/InternalError.html +1 -1
- data/doc/SDM/Kubernetes.html +4 -58
- data/doc/SDM/KubernetesBasicAuth.html +3 -3
- data/doc/SDM/KubernetesServiceAccount.html +3 -3
- data/doc/SDM/Maria.html +3 -3
- data/doc/SDM/Memcached.html +3 -3
- data/doc/SDM/Memsql.html +3 -3
- data/doc/SDM/MongoHost.html +3 -3
- data/doc/SDM/MongoLegacyHost.html +3 -3
- data/doc/SDM/MongoLegacyReplicaset.html +3 -3
- data/doc/SDM/MongoReplicaSet.html +3 -3
- data/doc/SDM/Mysql.html +3 -3
- data/doc/SDM/NodeCreateResponse.html +3 -3
- data/doc/SDM/NodeDeleteResponse.html +3 -3
- data/doc/SDM/NodeGetResponse.html +3 -3
- data/doc/SDM/NodeUpdateResponse.html +3 -3
- data/doc/SDM/Nodes.html +11 -11
- data/doc/SDM/NotFoundError.html +1 -1
- data/doc/SDM/Oracle.html +3 -3
- data/doc/SDM/PermissionError.html +1 -1
- data/doc/SDM/Plumbing.html +751 -421
- data/doc/SDM/Postgres.html +3 -3
- data/doc/SDM/Presto.html +3 -3
- data/doc/SDM/RDP.html +3 -3
- data/doc/SDM/RPCError.html +1 -1
- data/doc/SDM/RateLimitError.html +1 -1
- data/doc/SDM/RateLimitMetadata.html +1 -1
- data/doc/SDM/Redis.html +3 -3
- data/doc/SDM/Redshift.html +3 -3
- data/doc/SDM/Relay.html +4 -4
- data/doc/SDM/ResourceCreateResponse.html +3 -3
- data/doc/SDM/ResourceDeleteResponse.html +3 -3
- data/doc/SDM/ResourceGetResponse.html +3 -3
- data/doc/SDM/ResourceUpdateResponse.html +3 -3
- data/doc/SDM/Resources.html +7 -7
- data/doc/SDM/Role.html +4 -4
- data/doc/SDM/RoleAttachment.html +3 -3
- data/doc/SDM/RoleAttachmentCreateResponse.html +3 -3
- data/doc/SDM/RoleAttachmentDeleteResponse.html +3 -3
- data/doc/SDM/RoleAttachmentGetResponse.html +3 -3
- data/doc/SDM/RoleAttachments.html +6 -6
- data/doc/SDM/RoleCreateResponse.html +3 -3
- data/doc/SDM/RoleDeleteResponse.html +3 -3
- data/doc/SDM/RoleGetResponse.html +3 -3
- data/doc/SDM/RoleGrant.html +3 -3
- data/doc/SDM/RoleGrantCreateResponse.html +3 -3
- data/doc/SDM/RoleGrantDeleteResponse.html +3 -3
- data/doc/SDM/RoleGrantGetResponse.html +3 -3
- data/doc/SDM/RoleGrants.html +6 -6
- data/doc/SDM/RoleUpdateResponse.html +3 -3
- data/doc/SDM/Roles.html +7 -7
- data/doc/SDM/SQLServer.html +3 -3
- data/doc/SDM/SSH.html +3 -3
- data/doc/SDM/SSHCert.html +3 -3
- data/doc/SDM/Service.html +1 -1
- data/doc/SDM/Snowflake.html +3 -3
- data/doc/SDM/Sybase.html +3 -3
- data/doc/SDM/SybaseIQ.html +3 -3
- data/doc/SDM/Teradata.html +3 -3
- data/doc/SDM/UpdateResponseMetadata.html +1 -1
- data/doc/SDM/User.html +1 -1
- data/doc/V1.html +17 -2
- data/doc/V1/AccountAttachments.html +1 -1
- data/doc/V1/AccountAttachments/Service.html +2 -2
- data/doc/V1/AccountGrants.html +1 -1
- data/doc/V1/AccountGrants/Service.html +1 -1
- data/doc/V1/Accounts.html +1 -1
- data/doc/V1/Accounts/Service.html +3 -3
- data/doc/V1/ControlPanel.html +113 -0
- data/doc/V1/ControlPanel/Service.html +119 -0
- data/doc/V1/Nodes.html +1 -1
- data/doc/V1/Nodes/Service.html +5 -5
- data/doc/V1/Resources.html +1 -1
- data/doc/V1/Resources/Service.html +1 -1
- data/doc/V1/RoleAttachments.html +1 -1
- data/doc/V1/RoleAttachments/Service.html +1 -1
- data/doc/V1/RoleGrants.html +1 -1
- data/doc/V1/RoleGrants/Service.html +1 -1
- data/doc/V1/Roles.html +1 -1
- data/doc/V1/Roles/Service.html +1 -1
- data/doc/V1/Tags.html +1 -1
- data/doc/created.rid +39 -45
- data/doc/css/rdoc.css +13 -5
- data/doc/examples/Gemfile.html +1 -11
- data/doc/index.html +12 -12
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search_index.js +1 -1
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js.gz +0 -0
- data/doc/lib/version.html +3 -13
- data/doc/strongdm_gemspec.html +0 -8
- data/doc/table_of_contents.html +232 -172
- data/lib/grpc/account_attachments_services_pb.rb +1 -1
- data/lib/grpc/accounts_services_pb.rb +3 -4
- data/lib/grpc/control_panel_pb.rb +39 -0
- data/lib/grpc/control_panel_services_pb.rb +37 -0
- data/lib/grpc/drivers_pb.rb +17 -12
- data/lib/grpc/nodes_services_pb.rb +3 -4
- data/lib/grpc/plumbing.rb +109 -30
- data/lib/models/porcelain.rb +117 -61
- data/lib/strongdm.rb +10 -9
- data/lib/svc.rb +52 -9
- data/lib/version +5 -5
- data/lib/version.rb +1 -1
- data/strongdm.gemspec +1 -1
- metadata +24 -26
- data/examples/Gemfile.lock +0 -14
- data/examples/README.md +0 -5
- data/examples/ldap-sync/ldapSync.rb +0 -290
- data/examples/okta-sync/Gemfile +0 -4
- data/examples/okta-sync/Gemfile.lock +0 -38
- data/examples/okta-sync/matchers.yml +0 -11
- data/examples/okta-sync/oktaSync.rb +0 -173
- data/examples/panicButton.rb +0 -138
data/lib/version.rb
CHANGED
data/strongdm.gemspec
CHANGED
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
|
7
7
|
s.platform = Gem::Platform::RUBY
|
|
8
8
|
s.authors = ["strongDM Team"]
|
|
9
9
|
s.email = ["sdk-feedback@strongdm.com"]
|
|
10
|
-
s.homepage = "
|
|
10
|
+
s.homepage = "https://github.com/strongdm/strongdm-sdk-ruby"
|
|
11
11
|
s.summary = "strongDM SDK for the Ruby programming language."
|
|
12
12
|
s.description = "strongDM Ruby Library for automating interactions with strongDM."
|
|
13
13
|
s.licenses = ["Apache-2.0"]
|
metadata
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: strongdm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- strongDM Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-09-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: grpc
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: 1.27.0
|
|
20
|
-
- - "
|
|
20
|
+
- - "~>"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
22
|
version: 1.27.0
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
|
-
- - "
|
|
27
|
+
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
29
|
version: 1.27.0
|
|
30
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: 1.27.0
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: grpc-tools
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: 1.27.0
|
|
40
|
-
- - "
|
|
40
|
+
- - "~>"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
42
|
version: 1.27.0
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
|
-
- - "
|
|
47
|
+
- - ">="
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
49
|
version: 1.27.0
|
|
50
|
-
- - "
|
|
50
|
+
- - "~>"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: 1.27.0
|
|
53
53
|
- !ruby/object:Gem::Dependency
|
|
54
54
|
name: openssl
|
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
|
56
56
|
requirements:
|
|
57
|
-
- - "
|
|
57
|
+
- - ">="
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
59
|
version: 2.1.2
|
|
60
|
-
- - "
|
|
60
|
+
- - "~>"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
62
|
version: 2.1.2
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
|
-
- - "
|
|
67
|
+
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: 2.1.2
|
|
70
|
-
- - "
|
|
70
|
+
- - "~>"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
72
|
version: 2.1.2
|
|
73
73
|
description: strongDM Ruby Library for automating interactions with strongDM.
|
|
@@ -118,8 +118,11 @@ files:
|
|
|
118
118
|
- doc/SDM/Client.html
|
|
119
119
|
- doc/SDM/Clustrix.html
|
|
120
120
|
- doc/SDM/Cockroach.html
|
|
121
|
+
- doc/SDM/ControlPanel.html
|
|
122
|
+
- doc/SDM/ControlPanelGetSSHCAPublicKeyResponse.html
|
|
121
123
|
- doc/SDM/CreateResponseMetadata.html
|
|
122
|
-
- doc/SDM/
|
|
124
|
+
- doc/SDM/DB2LUW.html
|
|
125
|
+
- doc/SDM/DB2i.html
|
|
123
126
|
- doc/SDM/DeadlineExceededError.html
|
|
124
127
|
- doc/SDM/DeleteResponseMetadata.html
|
|
125
128
|
- doc/SDM/Druid.html
|
|
@@ -201,6 +204,8 @@ files:
|
|
|
201
204
|
- doc/V1/AccountGrants/Service.html
|
|
202
205
|
- doc/V1/Accounts.html
|
|
203
206
|
- doc/V1/Accounts/Service.html
|
|
207
|
+
- doc/V1/ControlPanel.html
|
|
208
|
+
- doc/V1/ControlPanel/Service.html
|
|
204
209
|
- doc/V1/Nodes.html
|
|
205
210
|
- doc/V1/Nodes/Service.html
|
|
206
211
|
- doc/V1/Resources.html
|
|
@@ -265,15 +270,7 @@ files:
|
|
|
265
270
|
- doc/strongdm_gemspec.html
|
|
266
271
|
- doc/table_of_contents.html
|
|
267
272
|
- examples/Gemfile
|
|
268
|
-
- examples/Gemfile.lock
|
|
269
|
-
- examples/README.md
|
|
270
|
-
- examples/ldap-sync/ldapSync.rb
|
|
271
273
|
- examples/listUsers.rb
|
|
272
|
-
- examples/okta-sync/Gemfile
|
|
273
|
-
- examples/okta-sync/Gemfile.lock
|
|
274
|
-
- examples/okta-sync/matchers.yml
|
|
275
|
-
- examples/okta-sync/oktaSync.rb
|
|
276
|
-
- examples/panicButton.rb
|
|
277
274
|
- lib/errors/errors.rb
|
|
278
275
|
- lib/grpc/account_attachments_pb.rb
|
|
279
276
|
- lib/grpc/account_attachments_services_pb.rb
|
|
@@ -281,6 +278,8 @@ files:
|
|
|
281
278
|
- lib/grpc/account_grants_services_pb.rb
|
|
282
279
|
- lib/grpc/accounts_pb.rb
|
|
283
280
|
- lib/grpc/accounts_services_pb.rb
|
|
281
|
+
- lib/grpc/control_panel_pb.rb
|
|
282
|
+
- lib/grpc/control_panel_services_pb.rb
|
|
284
283
|
- lib/grpc/drivers_pb.rb
|
|
285
284
|
- lib/grpc/nodes_pb.rb
|
|
286
285
|
- lib/grpc/nodes_services_pb.rb
|
|
@@ -303,7 +302,7 @@ files:
|
|
|
303
302
|
- lib/version
|
|
304
303
|
- lib/version.rb
|
|
305
304
|
- strongdm.gemspec
|
|
306
|
-
homepage:
|
|
305
|
+
homepage: https://github.com/strongdm/strongdm-sdk-ruby
|
|
307
306
|
licenses:
|
|
308
307
|
- Apache-2.0
|
|
309
308
|
metadata: {}
|
|
@@ -322,8 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
322
321
|
- !ruby/object:Gem::Version
|
|
323
322
|
version: 1.3.6
|
|
324
323
|
requirements: []
|
|
325
|
-
|
|
326
|
-
rubygems_version: 2.7.6
|
|
324
|
+
rubygems_version: 3.0.3
|
|
327
325
|
signing_key:
|
|
328
326
|
specification_version: 4
|
|
329
327
|
summary: strongDM SDK for the Ruby programming language.
|
data/examples/Gemfile.lock
DELETED
data/examples/README.md
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
# Copyright 2020 StrongDM Inc
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
#
|
|
15
|
-
require "yaml"
|
|
16
|
-
require "strongdm"
|
|
17
|
-
require "net/ldap"
|
|
18
|
-
require "optparse"
|
|
19
|
-
require "logger"
|
|
20
|
-
|
|
21
|
-
# This script reads from an LDAP server and does the following writes in StrongDM:
|
|
22
|
-
# - creates roles for each configured organizational unit (OU)
|
|
23
|
-
# - creates accounts for users in those OUs
|
|
24
|
-
# - attaches those accounts to their corresponding roles
|
|
25
|
-
# - grants resources to these roles based on configured filters
|
|
26
|
-
# - detaches accounts from roles, deletes accounts, and deletes grants as necessary
|
|
27
|
-
|
|
28
|
-
# IMPORTANT CAVEATS:
|
|
29
|
-
# - this script can pull existing StrongDM users into its purview. then, if the
|
|
30
|
-
# user is removed from LDAP, it will delete the user.
|
|
31
|
-
# - if you need to delete an entire role / OU, you'll need to do it manually.
|
|
32
|
-
# this script does not touch roles that are not in the config file.
|
|
33
|
-
|
|
34
|
-
# Example config file:
|
|
35
|
-
|
|
36
|
-
# organizationalUnits:
|
|
37
|
-
# - dn: OU=Other-OU,DC=j42,DC=xyz
|
|
38
|
-
# role: Other-OU
|
|
39
|
-
# resources:
|
|
40
|
-
# - name:*Other-OU*
|
|
41
|
-
# - name:*Multi*
|
|
42
|
-
# - dn: OU=admins,DC=j42,DC=xyz
|
|
43
|
-
# role: admins
|
|
44
|
-
# resources:
|
|
45
|
-
# - name:*admins*
|
|
46
|
-
# - dn: OU=People,DC=j42,DC=xyz
|
|
47
|
-
# role: People
|
|
48
|
-
# resources:
|
|
49
|
-
# - name:*People*
|
|
50
|
-
|
|
51
|
-
SDM_API_ACCESS_KEY = ENV.fetch("SDM_API_ACCESS_KEY", "")
|
|
52
|
-
SDM_API_SECRET_KEY = ENV.fetch("SDM_API_SECRET_KEY", "")
|
|
53
|
-
LDAP_HOST = ENV.fetch("LDAP_HOST", "")
|
|
54
|
-
LDAP_BIND_DN = ENV.fetch("LDAP_BIND_DN", "")
|
|
55
|
-
LDAP_PASSWORD = ENV.fetch("LDAP_PASSWORD", "")
|
|
56
|
-
|
|
57
|
-
# gets the first item in a list or generator
|
|
58
|
-
def first(attrib)
|
|
59
|
-
result = nil
|
|
60
|
-
attrib.each do |item|
|
|
61
|
-
if result == nil
|
|
62
|
-
result = item
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
result
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def ldap_sync
|
|
69
|
-
if SDM_API_ACCESS_KEY == "" || SDM_API_SECRET_KEY == "" || LDAP_BIND_DN == ""
|
|
70
|
-
puts "SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, and LDAP_BIND_DN must be set"
|
|
71
|
-
exit 1
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
plan = false
|
|
75
|
-
verbose = false
|
|
76
|
-
configPath = "config.yml"
|
|
77
|
-
OptionParser.new do |opts|
|
|
78
|
-
opts.banner = "Usage ldapSync.rb [options]"
|
|
79
|
-
opts.on("-p", "--plan", "calculate changes but do not apply them") do |p|
|
|
80
|
-
plan = p
|
|
81
|
-
end
|
|
82
|
-
opts.on("-v", "--verbose", "print detailed report") do |v|
|
|
83
|
-
verbose = v
|
|
84
|
-
end
|
|
85
|
-
opts.on("-c", "--config FILE", "specify path to config YAML file (default: 'config.yml')") do |v|
|
|
86
|
-
configPath = v
|
|
87
|
-
end
|
|
88
|
-
end.parse!
|
|
89
|
-
|
|
90
|
-
begin
|
|
91
|
-
config = YAML.load(File.read(configPath))
|
|
92
|
-
rescue StandardError => ex
|
|
93
|
-
raise ex, "failed to parse #{configPath}"
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
begin
|
|
97
|
-
sdmClient = SDM::Client.new(SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, host: "api.strongdmdev.com:443")
|
|
98
|
-
rescue SDM::RPCError => ex
|
|
99
|
-
raise ex, "failed to create StrongDM client"
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
ldap = Net::LDAP.new
|
|
103
|
-
ldap.host = LDAP_HOST
|
|
104
|
-
ldap.auth LDAP_BIND_DN, LDAP_PASSWORD
|
|
105
|
-
if not ldap.bind
|
|
106
|
-
puts "failed to bind LDAP connection - authentication error"
|
|
107
|
-
exit 1
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
sdmRoles = {} # map of name to ID
|
|
111
|
-
sdmAccounts = {} # map of email to id
|
|
112
|
-
sdmResources = {} # map of ID to name
|
|
113
|
-
sdmAccountsById = {} # map of id to { :email, :firstName, :lastName }
|
|
114
|
-
sdmAccountsWithAttachments = {} # map of email to id of all accounts that are in the roles we're interested in
|
|
115
|
-
sdmAccountAttachments = {} # map of role name to list of emails
|
|
116
|
-
sdmRoleGrants = {} # map of role name to list of { :resourceId, :grantId }
|
|
117
|
-
ldapRoles = [] # list of names
|
|
118
|
-
ldapAccounts = {} # map of email to { :firstName, :lastName }
|
|
119
|
-
ldapAccountAttachments = {} # map of role name to list of emails
|
|
120
|
-
desiredRoleGrants = {} # map of role name to list of resource IDs
|
|
121
|
-
|
|
122
|
-
# get SDM accounts
|
|
123
|
-
sdmClient.accounts.list("").each do |account|
|
|
124
|
-
sdmAccounts[account.email] = account.id
|
|
125
|
-
sdmAccountsById[account.id] = { :email => account.email, :firstName => account.first_name, :lastName => account.last_name }
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# get SDM resources
|
|
129
|
-
sdmClient.resources.list("").each do |resource|
|
|
130
|
-
sdmResources[resource.id] = resource.name
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# loop through OUs
|
|
134
|
-
config["organizationalUnits"].each do |ou|
|
|
135
|
-
|
|
136
|
-
# get SDM state for this OU
|
|
137
|
-
role = first(sdmClient.roles.list("name:?", ou["role"]))
|
|
138
|
-
if role
|
|
139
|
-
sdmRoles[role.name] = role.id
|
|
140
|
-
|
|
141
|
-
# get accounts attached to this role
|
|
142
|
-
accountEmails = []
|
|
143
|
-
sdmClient.account_attachments.list("roleid:?", role.id).each do |attachment|
|
|
144
|
-
sdmAccount = sdmAccountsById[attachment.account_id]
|
|
145
|
-
email = sdmAccount[:email]
|
|
146
|
-
sdmAccountsWithAttachments[email] = attachment.account_id
|
|
147
|
-
accountEmails.push(email)
|
|
148
|
-
end
|
|
149
|
-
sdmAccountAttachments[role.name] = accountEmails
|
|
150
|
-
|
|
151
|
-
# get resources granted to this role
|
|
152
|
-
roleGrants = []
|
|
153
|
-
sdmClient.role_grants.list("roleid:?", role.id).each do |grant|
|
|
154
|
-
roleGrants.push({ :resourceId => grant.resource_id, :grantId => grant.id })
|
|
155
|
-
end
|
|
156
|
-
sdmRoleGrants[role.name] = roleGrants
|
|
157
|
-
|
|
158
|
-
# get resources that we want to grant to this role
|
|
159
|
-
filteredResources = {} # map of resource ID to true (to prevent duplicates)
|
|
160
|
-
filters = ou["resources"] # list of filter strings
|
|
161
|
-
if filters
|
|
162
|
-
filters.each do |filter|
|
|
163
|
-
sdmClient.resources.list(filter).each do |resource|
|
|
164
|
-
filteredResources[resource.id] = true
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
desiredRoleGrants[role.name] = filteredResources.keys
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# get LDAP state for this OU
|
|
172
|
-
ldapRoles.push(ou["role"].to_s)
|
|
173
|
-
roleAccounts = []
|
|
174
|
-
ldap.search(:base => ou["dn"], :filter => Net::LDAP::Filter.eq("objectclass", "user"), :return_result => false) do |entry|
|
|
175
|
-
ldapAccounts[first(entry.mail).to_s] = {
|
|
176
|
-
:firstName => first(entry.givenname).to_s,
|
|
177
|
-
:lastName => first(entry.sn).to_s,
|
|
178
|
-
}
|
|
179
|
-
roleAccounts.push(first(entry.mail).to_s)
|
|
180
|
-
end
|
|
181
|
-
ldapAccountAttachments[ou["role"].to_s] = roleAccounts
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
# compute diff
|
|
185
|
-
report = {
|
|
186
|
-
:createRoles => [],
|
|
187
|
-
:deleteAccounts => [],
|
|
188
|
-
:updateAccounts => [],
|
|
189
|
-
:createAccounts => [],
|
|
190
|
-
:createAccountAttachments => [],
|
|
191
|
-
:deleteAccountAttachments => [],
|
|
192
|
-
:deleteRoleGrants => [],
|
|
193
|
-
:createRoleGrants => [],
|
|
194
|
-
}
|
|
195
|
-
# createRoles
|
|
196
|
-
ldapRoles.each do |roleName|
|
|
197
|
-
next if sdmRoles[roleName]
|
|
198
|
-
report[:createRoles].push(roleName)
|
|
199
|
-
next if plan
|
|
200
|
-
response = sdmClient.roles.create(SDM::Role.new(name: roleName))
|
|
201
|
-
sdmRoles[roleName] = response.role.id
|
|
202
|
-
end
|
|
203
|
-
# deleteAccounts
|
|
204
|
-
sdmAccountsWithAttachments.each do |email, id|
|
|
205
|
-
next if ldapAccounts[email]
|
|
206
|
-
report[:deleteAccounts].push(email)
|
|
207
|
-
next if plan
|
|
208
|
-
sdmClient.accounts.delete(id)
|
|
209
|
-
end
|
|
210
|
-
# updateAccounts
|
|
211
|
-
sdmAccountsWithAttachments.each do |email, id|
|
|
212
|
-
ldapAccount = ldapAccounts[email]
|
|
213
|
-
next if not ldapAccount
|
|
214
|
-
sdmAccount = sdmAccountsById[id]
|
|
215
|
-
next if sdmAccount[:firstName] == ldapAccount[:firstName] and sdmAccount[:lastName] == ldapAccount[:lastName]
|
|
216
|
-
report[:updateAccounts].push(email)
|
|
217
|
-
next if plan
|
|
218
|
-
sdmClient.accounts.update(SDM::User.new(id: id, first_name: ldapAccount[:firstName], last_name: ldapAccount[:lastName]))
|
|
219
|
-
end
|
|
220
|
-
# createAccounts
|
|
221
|
-
ldapAccounts.each do |email, account|
|
|
222
|
-
next if sdmAccounts[email]
|
|
223
|
-
report[:createAccounts].push(email)
|
|
224
|
-
next if plan
|
|
225
|
-
response = sdmClient.accounts.create(SDM::User.new(email: email, first_name: account[:firstName], last_name: account[:lastName]))
|
|
226
|
-
sdmAccounts[response.account.email] = response.account.id
|
|
227
|
-
end
|
|
228
|
-
# deleteAccountAttachments
|
|
229
|
-
sdmAccountAttachments.each do |roleName, accounts|
|
|
230
|
-
roleId = sdmRoles[roleName]
|
|
231
|
-
ldapAccountsInRole = ldapAccountAttachments[roleName]
|
|
232
|
-
accounts.each do |email|
|
|
233
|
-
next if ldapAccountsInRole and ldapAccountsInRole.include? email
|
|
234
|
-
report[:deleteAccountAttachments].push({ :role => roleName, :account => email })
|
|
235
|
-
next if plan
|
|
236
|
-
accountId = sdmAccounts[email]
|
|
237
|
-
attachment = first(sdmClient.account_attachments.list("accountid:? roleid:?", accountId, roleId))
|
|
238
|
-
next if not attachment # already deleted by the deleteAccounts step
|
|
239
|
-
sdmClient.account_attachments.delete(attachment.id)
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
# createAccountAttachments
|
|
243
|
-
ldapAccountAttachments.each do |roleName, accounts|
|
|
244
|
-
roleId = sdmRoles[roleName]
|
|
245
|
-
sdmAccountsInRole = sdmAccountAttachments[roleName]
|
|
246
|
-
accounts.each do |email|
|
|
247
|
-
next if sdmAccountsInRole and sdmAccountsInRole.include? email
|
|
248
|
-
report[:createAccountAttachments].push({ :role => roleName, :account => email })
|
|
249
|
-
accountId = sdmAccounts[email]
|
|
250
|
-
next if plan
|
|
251
|
-
sdmClient.account_attachments.create(SDM::AccountAttachment.new(account_id: accountId, role_id: roleId))
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
# deleteRoleGrants
|
|
255
|
-
sdmRoleGrants.each do |roleName, roleGrants|
|
|
256
|
-
desired = desiredRoleGrants[roleName]
|
|
257
|
-
roleGrants.each do |grant|
|
|
258
|
-
next if desired and desired.include? grant[:resourceId]
|
|
259
|
-
resourceName = sdmResources[grant[:resourceId]]
|
|
260
|
-
report[:deleteRoleGrants].push({ :role => roleName, :resource => resourceName })
|
|
261
|
-
next if plan
|
|
262
|
-
sdmClient.role_grants.delete(grant[:grantId])
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
# createRoleGrants
|
|
266
|
-
desiredRoleGrants.each do |roleName, roleGrants|
|
|
267
|
-
roleId = sdmRoles[roleName]
|
|
268
|
-
existing = sdmRoleGrants[roleName]
|
|
269
|
-
roleGrants.each do |resourceId|
|
|
270
|
-
next if existing and existing.find { |existingGrant| existingGrant[:resourceId] == resourceId }
|
|
271
|
-
resourceName = sdmResources[resourceId]
|
|
272
|
-
report[:createRoleGrants].push({ :role => roleName, :resource => resourceName })
|
|
273
|
-
next if plan
|
|
274
|
-
sdmClient.role_grants.create(SDM::RoleGrant.new(role_id: roleId, resource_id: resourceId))
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
if verbose
|
|
278
|
-
puts JSON.pretty_generate(report)
|
|
279
|
-
else
|
|
280
|
-
puts "Create #{report[:createRoles].length} roles"
|
|
281
|
-
puts "Delete #{report[:deleteAccounts].length} accounts"
|
|
282
|
-
puts "Create #{report[:createAccounts].length} accounts"
|
|
283
|
-
puts "Delete #{report[:deleteAccountAttachments].length} account attachments"
|
|
284
|
-
puts "Create #{report[:createAccountAttachments].length} account attachments"
|
|
285
|
-
puts "Delete #{report[:deleteRoleGrants].length} role grants"
|
|
286
|
-
puts "Create #{report[:createRoleGrants].length} role grants"
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
ldap_sync
|