strongdm 1.0.7 → 1.0.8
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 +26 -7
- data/doc/LICENSE.html +1 -11
- data/doc/Object.html +1 -679
- data/doc/README_md.html +31 -20
- data/doc/SDM.html +1 -1
- data/doc/SDM/AKS.html +3 -3
- data/doc/SDM/AKSBasicAuth.html +3 -3
- data/doc/SDM/AKSServiceAccount.html +3 -3
- data/doc/SDM/AccountAttachment.html +1 -1
- 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 +1 -1
- 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 +1 -1
- data/doc/SDM/AlreadyExistsError.html +1 -1
- data/doc/SDM/AmazonEKS.html +3 -3
- data/doc/SDM/AmazonES.html +3 -3
- data/doc/SDM/Athena.html +1 -1
- 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 +1 -1
- data/doc/SDM/Cassandra.html +1 -1
- data/doc/SDM/Citus.html +3 -3
- data/doc/SDM/Client.html +1 -1
- data/doc/SDM/Clustrix.html +3 -3
- data/doc/SDM/Cockroach.html +3 -3
- data/doc/SDM/CreateResponseMetadata.html +1 -1
- data/doc/SDM/DB2LUW.html +391 -0
- 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 +3 -3
- data/doc/SDM/GetResponseMetadata.html +1 -1
- data/doc/SDM/GoogleGKE.html +3 -3
- 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 +3 -3
- 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 +1 -1
- 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 +501 -317
- 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 +3 -3
- 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 +1 -1
- data/doc/SDM/Role.html +3 -3
- 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 +1 -1
- 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 +1 -1
- data/doc/SDM/RoleUpdateResponse.html +3 -3
- data/doc/SDM/Roles.html +1 -1
- 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 +7 -2
- data/doc/V1/AccountAttachments.html +1 -1
- data/doc/V1/AccountAttachments/Service.html +1 -1
- 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 +1 -1
- data/doc/V1/Nodes.html +1 -1
- data/doc/V1/Nodes/Service.html +1 -1
- 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 +35 -45
- data/doc/css/rdoc.css +13 -5
- data/doc/examples/Gemfile.html +1 -11
- data/doc/index.html +4 -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/table_of_contents.html +160 -160
- data/lib/grpc/drivers_pb.rb +17 -3
- data/lib/grpc/plumbing.rb +70 -12
- data/lib/models/porcelain.rb +76 -1
- data/lib/version +5 -5
- data/lib/version.rb +1 -1
- metadata +4 -12
- data/examples/Gemfile +0 -3
- data/examples/Gemfile.lock +0 -14
- data/examples/README.md +0 -5
- data/examples/ldap-sync/ldapSync.rb +0 -290
- data/examples/listUsers.rb +0 -21
- 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/grpc/drivers_pb.rb
CHANGED
@@ -27,7 +27,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
27
27
|
optional :athena, :message, 100, "v1.Athena"
|
28
28
|
optional :big_query, :message, 200, "v1.BigQuery"
|
29
29
|
optional :cassandra, :message, 300, "v1.Cassandra"
|
30
|
-
optional :
|
30
|
+
optional :db_2_i, :message, 2400, "v1.DB2I"
|
31
|
+
optional :db_2_luw, :message, 2200, "v1.DB2LUW"
|
31
32
|
optional :druid, :message, 400, "v1.Druid"
|
32
33
|
optional :dynamo_db, :message, 500, "v1.DynamoDB"
|
33
34
|
optional :amazon_es, :message, 600, "v1.AmazonES"
|
@@ -107,7 +108,19 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
107
108
|
optional :port, :int32, 5
|
108
109
|
optional :tls_required, :bool, 6
|
109
110
|
end
|
110
|
-
add_message "v1.
|
111
|
+
add_message "v1.DB2I" do
|
112
|
+
optional :id, :string, 32768
|
113
|
+
optional :name, :string, 32769
|
114
|
+
optional :healthy, :bool, 32770
|
115
|
+
optional :tags, :message, 32771, "v1.Tags"
|
116
|
+
optional :hostname, :string, 1
|
117
|
+
optional :username, :string, 2
|
118
|
+
optional :password, :string, 3
|
119
|
+
optional :port_override, :int32, 4
|
120
|
+
optional :port, :int32, 5
|
121
|
+
optional :tls_required, :bool, 7
|
122
|
+
end
|
123
|
+
add_message "v1.DB2LUW" do
|
111
124
|
optional :id, :string, 32768
|
112
125
|
optional :name, :string, 32769
|
113
126
|
optional :healthy, :bool, 32770
|
@@ -651,7 +664,8 @@ module V1
|
|
651
664
|
Athena = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.Athena").msgclass
|
652
665
|
BigQuery = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.BigQuery").msgclass
|
653
666
|
Cassandra = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.Cassandra").msgclass
|
654
|
-
|
667
|
+
DB2I = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DB2I").msgclass
|
668
|
+
DB2LUW = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DB2LUW").msgclass
|
655
669
|
Druid = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.Druid").msgclass
|
656
670
|
DynamoDB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DynamoDB").msgclass
|
657
671
|
AmazonES = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AmazonES").msgclass
|
data/lib/grpc/plumbing.rb
CHANGED
@@ -854,8 +854,11 @@ module SDM
|
|
854
854
|
if porcelain.instance_of? Cassandra
|
855
855
|
plumbing.cassandra = convert_cassandra_to_plumbing(porcelain)
|
856
856
|
end
|
857
|
-
if porcelain.instance_of?
|
858
|
-
plumbing.
|
857
|
+
if porcelain.instance_of? DB2I
|
858
|
+
plumbing.db_2_i = convert_db_2_i_to_plumbing(porcelain)
|
859
|
+
end
|
860
|
+
if porcelain.instance_of? DB2LUW
|
861
|
+
plumbing.db_2_luw = convert_db_2_luw_to_plumbing(porcelain)
|
859
862
|
end
|
860
863
|
if porcelain.instance_of? Druid
|
861
864
|
plumbing.druid = convert_druid_to_plumbing(porcelain)
|
@@ -1002,8 +1005,11 @@ module SDM
|
|
1002
1005
|
if plumbing.cassandra != nil
|
1003
1006
|
return convert_cassandra_to_porcelain(plumbing.cassandra)
|
1004
1007
|
end
|
1005
|
-
if plumbing.
|
1006
|
-
return
|
1008
|
+
if plumbing.db_2_i != nil
|
1009
|
+
return convert_db_2_i_to_porcelain(plumbing.db_2_i)
|
1010
|
+
end
|
1011
|
+
if plumbing.db_2_luw != nil
|
1012
|
+
return convert_db_2_luw_to_porcelain(plumbing.db_2_luw)
|
1007
1013
|
end
|
1008
1014
|
if plumbing.druid != nil
|
1009
1015
|
return convert_druid_to_porcelain(plumbing.druid)
|
@@ -1304,11 +1310,63 @@ module SDM
|
|
1304
1310
|
end
|
1305
1311
|
items
|
1306
1312
|
end
|
1307
|
-
def self.
|
1313
|
+
def self.convert_db_2_i_to_porcelain(plumbing)
|
1314
|
+
if plumbing == nil
|
1315
|
+
return nil
|
1316
|
+
end
|
1317
|
+
porcelain = DB2I.new()
|
1318
|
+
porcelain.id = (plumbing.id)
|
1319
|
+
porcelain.name = (plumbing.name)
|
1320
|
+
porcelain.healthy = (plumbing.healthy)
|
1321
|
+
porcelain.tags = convert_tags_to_porcelain(plumbing.tags)
|
1322
|
+
porcelain.hostname = (plumbing.hostname)
|
1323
|
+
porcelain.username = (plumbing.username)
|
1324
|
+
porcelain.password = (plumbing.password)
|
1325
|
+
porcelain.port_override = (plumbing.port_override)
|
1326
|
+
porcelain.port = (plumbing.port)
|
1327
|
+
porcelain.tls_required = (plumbing.tls_required)
|
1328
|
+
porcelain
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
def self.convert_db_2_i_to_plumbing(porcelain)
|
1332
|
+
if porcelain == nil
|
1333
|
+
return nil
|
1334
|
+
end
|
1335
|
+
plumbing = V1::DB2I.new()
|
1336
|
+
plumbing.id = (porcelain.id) unless porcelain.id == nil
|
1337
|
+
plumbing.name = (porcelain.name) unless porcelain.name == nil
|
1338
|
+
plumbing.healthy = (porcelain.healthy) unless porcelain.healthy == nil
|
1339
|
+
plumbing.tags = convert_tags_to_plumbing(porcelain.tags) unless porcelain.tags == nil
|
1340
|
+
plumbing.hostname = (porcelain.hostname) unless porcelain.hostname == nil
|
1341
|
+
plumbing.username = (porcelain.username) unless porcelain.username == nil
|
1342
|
+
plumbing.password = (porcelain.password) unless porcelain.password == nil
|
1343
|
+
plumbing.port_override = (porcelain.port_override) unless porcelain.port_override == nil
|
1344
|
+
plumbing.port = (porcelain.port) unless porcelain.port == nil
|
1345
|
+
plumbing.tls_required = (porcelain.tls_required) unless porcelain.tls_required == nil
|
1346
|
+
plumbing
|
1347
|
+
end
|
1348
|
+
def self.convert_repeated_db_2_i_to_plumbing(porcelains)
|
1349
|
+
items = Array.new
|
1350
|
+
porcelains.each do |porcelain|
|
1351
|
+
plumbing = convert_db_2_i_to_plumbing(porcelain)
|
1352
|
+
items.append(plumbing)
|
1353
|
+
end
|
1354
|
+
items
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
def self.convert_repeated_db_2_i_to_porcelain(plumbings)
|
1358
|
+
items = Array.new
|
1359
|
+
plumbings.each do |plumbing|
|
1360
|
+
porcelain = convert_db_2_i_to_porcelain(plumbing)
|
1361
|
+
items.append(porcelain)
|
1362
|
+
end
|
1363
|
+
items
|
1364
|
+
end
|
1365
|
+
def self.convert_db_2_luw_to_porcelain(plumbing)
|
1308
1366
|
if plumbing == nil
|
1309
1367
|
return nil
|
1310
1368
|
end
|
1311
|
-
porcelain =
|
1369
|
+
porcelain = DB2LUW.new()
|
1312
1370
|
porcelain.id = (plumbing.id)
|
1313
1371
|
porcelain.name = (plumbing.name)
|
1314
1372
|
porcelain.healthy = (plumbing.healthy)
|
@@ -1322,11 +1380,11 @@ module SDM
|
|
1322
1380
|
porcelain
|
1323
1381
|
end
|
1324
1382
|
|
1325
|
-
def self.
|
1383
|
+
def self.convert_db_2_luw_to_plumbing(porcelain)
|
1326
1384
|
if porcelain == nil
|
1327
1385
|
return nil
|
1328
1386
|
end
|
1329
|
-
plumbing = V1::
|
1387
|
+
plumbing = V1::DB2LUW.new()
|
1330
1388
|
plumbing.id = (porcelain.id) unless porcelain.id == nil
|
1331
1389
|
plumbing.name = (porcelain.name) unless porcelain.name == nil
|
1332
1390
|
plumbing.healthy = (porcelain.healthy) unless porcelain.healthy == nil
|
@@ -1339,19 +1397,19 @@ module SDM
|
|
1339
1397
|
plumbing.port = (porcelain.port) unless porcelain.port == nil
|
1340
1398
|
plumbing
|
1341
1399
|
end
|
1342
|
-
def self.
|
1400
|
+
def self.convert_repeated_db_2_luw_to_plumbing(porcelains)
|
1343
1401
|
items = Array.new
|
1344
1402
|
porcelains.each do |porcelain|
|
1345
|
-
plumbing =
|
1403
|
+
plumbing = convert_db_2_luw_to_plumbing(porcelain)
|
1346
1404
|
items.append(plumbing)
|
1347
1405
|
end
|
1348
1406
|
items
|
1349
1407
|
end
|
1350
1408
|
|
1351
|
-
def self.
|
1409
|
+
def self.convert_repeated_db_2_luw_to_porcelain(plumbings)
|
1352
1410
|
items = Array.new
|
1353
1411
|
plumbings.each do |plumbing|
|
1354
|
-
porcelain =
|
1412
|
+
porcelain = convert_db_2_luw_to_porcelain(plumbing)
|
1355
1413
|
items.append(porcelain)
|
1356
1414
|
end
|
1357
1415
|
items
|
data/lib/models/porcelain.rb
CHANGED
@@ -834,7 +834,82 @@ module SDM
|
|
834
834
|
end
|
835
835
|
end
|
836
836
|
|
837
|
-
class
|
837
|
+
class DB2I
|
838
|
+
# Unique identifier of the Resource.
|
839
|
+
attr_accessor :id
|
840
|
+
# Unique human-readable name of the Resource.
|
841
|
+
attr_accessor :name
|
842
|
+
# True if the datasource is reachable and the credentials are valid.
|
843
|
+
attr_accessor :healthy
|
844
|
+
# Tags is a map of key, value pairs.
|
845
|
+
attr_accessor :tags
|
846
|
+
|
847
|
+
attr_accessor :hostname
|
848
|
+
|
849
|
+
attr_accessor :username
|
850
|
+
|
851
|
+
attr_accessor :password
|
852
|
+
|
853
|
+
attr_accessor :port_override
|
854
|
+
|
855
|
+
attr_accessor :port
|
856
|
+
|
857
|
+
attr_accessor :tls_required
|
858
|
+
|
859
|
+
def initialize(
|
860
|
+
id: nil,
|
861
|
+
name: nil,
|
862
|
+
healthy: nil,
|
863
|
+
tags: nil,
|
864
|
+
hostname: nil,
|
865
|
+
username: nil,
|
866
|
+
password: nil,
|
867
|
+
port_override: nil,
|
868
|
+
port: nil,
|
869
|
+
tls_required: nil
|
870
|
+
)
|
871
|
+
if id != nil
|
872
|
+
@id = id
|
873
|
+
end
|
874
|
+
if name != nil
|
875
|
+
@name = name
|
876
|
+
end
|
877
|
+
if healthy != nil
|
878
|
+
@healthy = healthy
|
879
|
+
end
|
880
|
+
if tags != nil
|
881
|
+
@tags = tags
|
882
|
+
end
|
883
|
+
if hostname != nil
|
884
|
+
@hostname = hostname
|
885
|
+
end
|
886
|
+
if username != nil
|
887
|
+
@username = username
|
888
|
+
end
|
889
|
+
if password != nil
|
890
|
+
@password = password
|
891
|
+
end
|
892
|
+
if port_override != nil
|
893
|
+
@port_override = port_override
|
894
|
+
end
|
895
|
+
if port != nil
|
896
|
+
@port = port
|
897
|
+
end
|
898
|
+
if tls_required != nil
|
899
|
+
@tls_required = tls_required
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
def to_json(options = {})
|
904
|
+
hash = {}
|
905
|
+
self.instance_variables.each do |var|
|
906
|
+
hash[var.id2name.delete_prefix("@")] = self.instance_variable_get var
|
907
|
+
end
|
908
|
+
hash.to_json
|
909
|
+
end
|
910
|
+
end
|
911
|
+
|
912
|
+
class DB2LUW
|
838
913
|
# Unique identifier of the Resource.
|
839
914
|
attr_accessor :id
|
840
915
|
# Unique human-readable name of the Resource.
|
data/lib/version
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# Copyright 2020 StrongDM Inc
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
5
5
|
# You may obtain a copy of the License at
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# Unless required by applicable law or agreed to in writing, software
|
10
10
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
module SDM
|
16
|
-
VERSION = "1.0.
|
16
|
+
VERSION = "1.0.8"
|
17
17
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.8
|
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-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grpc
|
@@ -120,6 +120,8 @@ files:
|
|
120
120
|
- doc/SDM/Cockroach.html
|
121
121
|
- doc/SDM/CreateResponseMetadata.html
|
122
122
|
- doc/SDM/DB2.html
|
123
|
+
- doc/SDM/DB2LUW.html
|
124
|
+
- doc/SDM/DB2i.html
|
123
125
|
- doc/SDM/DeadlineExceededError.html
|
124
126
|
- doc/SDM/DeleteResponseMetadata.html
|
125
127
|
- doc/SDM/Druid.html
|
@@ -264,16 +266,6 @@ files:
|
|
264
266
|
- doc/lib/version.html
|
265
267
|
- doc/strongdm_gemspec.html
|
266
268
|
- doc/table_of_contents.html
|
267
|
-
- examples/Gemfile
|
268
|
-
- examples/Gemfile.lock
|
269
|
-
- examples/README.md
|
270
|
-
- examples/ldap-sync/ldapSync.rb
|
271
|
-
- 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
269
|
- lib/errors/errors.rb
|
278
270
|
- lib/grpc/account_attachments_pb.rb
|
279
271
|
- lib/grpc/account_attachments_services_pb.rb
|
data/examples/Gemfile
DELETED
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
|