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.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -7
  3. data/doc/LICENSE.html +1 -11
  4. data/doc/Object.html +1 -679
  5. data/doc/README_md.html +31 -20
  6. data/doc/SDM.html +1 -1
  7. data/doc/SDM/AKS.html +3 -3
  8. data/doc/SDM/AKSBasicAuth.html +3 -3
  9. data/doc/SDM/AKSServiceAccount.html +3 -3
  10. data/doc/SDM/AccountAttachment.html +1 -1
  11. data/doc/SDM/AccountAttachmentCreateResponse.html +1 -1
  12. data/doc/SDM/AccountAttachmentDeleteResponse.html +1 -1
  13. data/doc/SDM/AccountAttachmentGetResponse.html +1 -1
  14. data/doc/SDM/AccountAttachments.html +1 -1
  15. data/doc/SDM/AccountCreateResponse.html +1 -1
  16. data/doc/SDM/AccountDeleteResponse.html +1 -1
  17. data/doc/SDM/AccountGetResponse.html +1 -1
  18. data/doc/SDM/AccountGrant.html +1 -1
  19. data/doc/SDM/AccountGrantCreateResponse.html +1 -1
  20. data/doc/SDM/AccountGrantDeleteResponse.html +1 -1
  21. data/doc/SDM/AccountGrantGetResponse.html +1 -1
  22. data/doc/SDM/AccountGrants.html +1 -1
  23. data/doc/SDM/AccountUpdateResponse.html +1 -1
  24. data/doc/SDM/Accounts.html +1 -1
  25. data/doc/SDM/AlreadyExistsError.html +1 -1
  26. data/doc/SDM/AmazonEKS.html +3 -3
  27. data/doc/SDM/AmazonES.html +3 -3
  28. data/doc/SDM/Athena.html +1 -1
  29. data/doc/SDM/AuroraMysql.html +3 -3
  30. data/doc/SDM/AuroraPostgres.html +3 -3
  31. data/doc/SDM/AuthenticationError.html +1 -1
  32. data/doc/SDM/BadRequestError.html +1 -1
  33. data/doc/SDM/BigQuery.html +1 -1
  34. data/doc/SDM/Cassandra.html +1 -1
  35. data/doc/SDM/Citus.html +3 -3
  36. data/doc/SDM/Client.html +1 -1
  37. data/doc/SDM/Clustrix.html +3 -3
  38. data/doc/SDM/Cockroach.html +3 -3
  39. data/doc/SDM/CreateResponseMetadata.html +1 -1
  40. data/doc/SDM/DB2LUW.html +391 -0
  41. data/doc/SDM/DB2i.html +391 -0
  42. data/doc/SDM/DeadlineExceededError.html +1 -1
  43. data/doc/SDM/DeleteResponseMetadata.html +1 -1
  44. data/doc/SDM/Druid.html +3 -3
  45. data/doc/SDM/DynamoDB.html +3 -3
  46. data/doc/SDM/Elastic.html +3 -3
  47. data/doc/SDM/ElasticacheRedis.html +3 -3
  48. data/doc/SDM/Gateway.html +3 -3
  49. data/doc/SDM/GetResponseMetadata.html +1 -1
  50. data/doc/SDM/GoogleGKE.html +3 -3
  51. data/doc/SDM/Greenplum.html +3 -3
  52. data/doc/SDM/HTTPAuth.html +3 -3
  53. data/doc/SDM/HTTPBasicAuth.html +3 -3
  54. data/doc/SDM/HTTPNoAuth.html +3 -3
  55. data/doc/SDM/InternalError.html +1 -1
  56. data/doc/SDM/Kubernetes.html +3 -3
  57. data/doc/SDM/KubernetesBasicAuth.html +3 -3
  58. data/doc/SDM/KubernetesServiceAccount.html +3 -3
  59. data/doc/SDM/Maria.html +3 -3
  60. data/doc/SDM/Memcached.html +3 -3
  61. data/doc/SDM/Memsql.html +3 -3
  62. data/doc/SDM/MongoHost.html +3 -3
  63. data/doc/SDM/MongoLegacyHost.html +3 -3
  64. data/doc/SDM/MongoLegacyReplicaset.html +3 -3
  65. data/doc/SDM/MongoReplicaSet.html +3 -3
  66. data/doc/SDM/Mysql.html +3 -3
  67. data/doc/SDM/NodeCreateResponse.html +3 -3
  68. data/doc/SDM/NodeDeleteResponse.html +3 -3
  69. data/doc/SDM/NodeGetResponse.html +3 -3
  70. data/doc/SDM/NodeUpdateResponse.html +3 -3
  71. data/doc/SDM/Nodes.html +1 -1
  72. data/doc/SDM/NotFoundError.html +1 -1
  73. data/doc/SDM/Oracle.html +3 -3
  74. data/doc/SDM/PermissionError.html +1 -1
  75. data/doc/SDM/Plumbing.html +501 -317
  76. data/doc/SDM/Postgres.html +3 -3
  77. data/doc/SDM/Presto.html +3 -3
  78. data/doc/SDM/RDP.html +3 -3
  79. data/doc/SDM/RPCError.html +1 -1
  80. data/doc/SDM/RateLimitError.html +1 -1
  81. data/doc/SDM/RateLimitMetadata.html +1 -1
  82. data/doc/SDM/Redis.html +3 -3
  83. data/doc/SDM/Redshift.html +3 -3
  84. data/doc/SDM/Relay.html +3 -3
  85. data/doc/SDM/ResourceCreateResponse.html +3 -3
  86. data/doc/SDM/ResourceDeleteResponse.html +3 -3
  87. data/doc/SDM/ResourceGetResponse.html +3 -3
  88. data/doc/SDM/ResourceUpdateResponse.html +3 -3
  89. data/doc/SDM/Resources.html +1 -1
  90. data/doc/SDM/Role.html +3 -3
  91. data/doc/SDM/RoleAttachment.html +3 -3
  92. data/doc/SDM/RoleAttachmentCreateResponse.html +3 -3
  93. data/doc/SDM/RoleAttachmentDeleteResponse.html +3 -3
  94. data/doc/SDM/RoleAttachmentGetResponse.html +3 -3
  95. data/doc/SDM/RoleAttachments.html +1 -1
  96. data/doc/SDM/RoleCreateResponse.html +3 -3
  97. data/doc/SDM/RoleDeleteResponse.html +3 -3
  98. data/doc/SDM/RoleGetResponse.html +3 -3
  99. data/doc/SDM/RoleGrant.html +3 -3
  100. data/doc/SDM/RoleGrantCreateResponse.html +3 -3
  101. data/doc/SDM/RoleGrantDeleteResponse.html +3 -3
  102. data/doc/SDM/RoleGrantGetResponse.html +3 -3
  103. data/doc/SDM/RoleGrants.html +1 -1
  104. data/doc/SDM/RoleUpdateResponse.html +3 -3
  105. data/doc/SDM/Roles.html +1 -1
  106. data/doc/SDM/SQLServer.html +3 -3
  107. data/doc/SDM/SSH.html +3 -3
  108. data/doc/SDM/SSHCert.html +3 -3
  109. data/doc/SDM/Service.html +1 -1
  110. data/doc/SDM/Snowflake.html +3 -3
  111. data/doc/SDM/Sybase.html +3 -3
  112. data/doc/SDM/SybaseIQ.html +3 -3
  113. data/doc/SDM/Teradata.html +3 -3
  114. data/doc/SDM/UpdateResponseMetadata.html +1 -1
  115. data/doc/SDM/User.html +1 -1
  116. data/doc/V1.html +7 -2
  117. data/doc/V1/AccountAttachments.html +1 -1
  118. data/doc/V1/AccountAttachments/Service.html +1 -1
  119. data/doc/V1/AccountGrants.html +1 -1
  120. data/doc/V1/AccountGrants/Service.html +1 -1
  121. data/doc/V1/Accounts.html +1 -1
  122. data/doc/V1/Accounts/Service.html +1 -1
  123. data/doc/V1/Nodes.html +1 -1
  124. data/doc/V1/Nodes/Service.html +1 -1
  125. data/doc/V1/Resources.html +1 -1
  126. data/doc/V1/Resources/Service.html +1 -1
  127. data/doc/V1/RoleAttachments.html +1 -1
  128. data/doc/V1/RoleAttachments/Service.html +1 -1
  129. data/doc/V1/RoleGrants.html +1 -1
  130. data/doc/V1/RoleGrants/Service.html +1 -1
  131. data/doc/V1/Roles.html +1 -1
  132. data/doc/V1/Roles/Service.html +1 -1
  133. data/doc/V1/Tags.html +1 -1
  134. data/doc/created.rid +35 -45
  135. data/doc/css/rdoc.css +13 -5
  136. data/doc/examples/Gemfile.html +1 -11
  137. data/doc/index.html +4 -12
  138. data/doc/js/navigation.js.gz +0 -0
  139. data/doc/js/search_index.js +1 -1
  140. data/doc/js/search_index.js.gz +0 -0
  141. data/doc/js/searcher.js.gz +0 -0
  142. data/doc/lib/version.html +3 -13
  143. data/doc/table_of_contents.html +160 -160
  144. data/lib/grpc/drivers_pb.rb +17 -3
  145. data/lib/grpc/plumbing.rb +70 -12
  146. data/lib/models/porcelain.rb +76 -1
  147. data/lib/version +5 -5
  148. data/lib/version.rb +1 -1
  149. metadata +4 -12
  150. data/examples/Gemfile +0 -3
  151. data/examples/Gemfile.lock +0 -14
  152. data/examples/README.md +0 -5
  153. data/examples/ldap-sync/ldapSync.rb +0 -290
  154. data/examples/listUsers.rb +0 -21
  155. data/examples/okta-sync/Gemfile +0 -4
  156. data/examples/okta-sync/Gemfile.lock +0 -38
  157. data/examples/okta-sync/matchers.yml +0 -11
  158. data/examples/okta-sync/oktaSync.rb +0 -173
  159. data/examples/panicButton.rb +0 -138
@@ -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 :db_2, :message, 2200, "v1.DB2"
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.DB2" do
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
- DB2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DB2").msgclass
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
@@ -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? DB2
858
- plumbing.db_2 = convert_db_2_to_plumbing(porcelain)
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.db_2 != nil
1006
- return convert_db_2_to_porcelain(plumbing.db_2)
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.convert_db_2_to_porcelain(plumbing)
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 = DB2.new()
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.convert_db_2_to_plumbing(porcelain)
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::DB2.new()
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.convert_repeated_db_2_to_plumbing(porcelains)
1400
+ def self.convert_repeated_db_2_luw_to_plumbing(porcelains)
1343
1401
  items = Array.new
1344
1402
  porcelains.each do |porcelain|
1345
- plumbing = convert_db_2_to_plumbing(porcelain)
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.convert_repeated_db_2_to_porcelain(plumbings)
1409
+ def self.convert_repeated_db_2_luw_to_porcelain(plumbings)
1352
1410
  items = Array.new
1353
1411
  plumbings.each do |plumbing|
1354
- porcelain = convert_db_2_to_porcelain(plumbing)
1412
+ porcelain = convert_db_2_luw_to_porcelain(plumbing)
1355
1413
  items.append(porcelain)
1356
1414
  end
1357
1415
  items
@@ -834,7 +834,82 @@ module SDM
834
834
  end
835
835
  end
836
836
 
837
- class DB2
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.
@@ -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.7"
16
+ VERSION = "1.0.8"
17
17
  end
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
  #
15
15
  module SDM
16
- VERSION = "1.0.7"
16
+ VERSION = "1.0.8"
17
17
  end
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.7
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-06-12 00:00:00.000000000 Z
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
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "strongdm"
@@ -1,14 +0,0 @@
1
- GEM
2
- specs:
3
- ipaddr (1.2.2)
4
- openssl (2.1.2)
5
- ipaddr
6
-
7
- PLATFORMS
8
- ruby
9
-
10
- DEPENDENCIES
11
- openssl
12
-
13
- BUNDLED WITH
14
- 1.17.2
@@ -1,5 +0,0 @@
1
- Prior to running examples, run:
2
-
3
- ```ShellSession
4
- $ bundler install
5
- ```
@@ -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