strongdm 1.0.5 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/doc/Object.html +324 -1
  3. data/doc/SDM/AKS.html +2 -2
  4. data/doc/SDM/AKSBasicAuth.html +2 -2
  5. data/doc/SDM/AKSServiceAccount.html +2 -2
  6. data/doc/SDM/AccountAttachment.html +2 -2
  7. data/doc/SDM/AccountAttachmentCreateResponse.html +2 -2
  8. data/doc/SDM/AccountAttachmentDeleteResponse.html +2 -2
  9. data/doc/SDM/AccountAttachmentGetResponse.html +2 -2
  10. data/doc/SDM/AccountAttachments.html +4 -6
  11. data/doc/SDM/AccountCreateResponse.html +2 -2
  12. data/doc/SDM/AccountDeleteResponse.html +2 -2
  13. data/doc/SDM/AccountGetResponse.html +2 -2
  14. data/doc/SDM/AccountGrant.html +2 -2
  15. data/doc/SDM/AccountGrantCreateResponse.html +2 -2
  16. data/doc/SDM/AccountGrantDeleteResponse.html +2 -2
  17. data/doc/SDM/AccountGrantGetResponse.html +2 -2
  18. data/doc/SDM/AccountGrants.html +5 -5
  19. data/doc/SDM/AccountUpdateResponse.html +2 -2
  20. data/doc/SDM/Accounts.html +6 -6
  21. data/doc/SDM/AmazonEKS.html +2 -2
  22. data/doc/SDM/AmazonES.html +2 -2
  23. data/doc/SDM/Athena.html +2 -2
  24. data/doc/SDM/AuroraMysql.html +2 -2
  25. data/doc/SDM/AuroraPostgres.html +2 -2
  26. data/doc/SDM/BigQuery.html +2 -2
  27. data/doc/SDM/Cassandra.html +2 -2
  28. data/doc/SDM/Citus.html +2 -2
  29. data/doc/SDM/Clustrix.html +2 -2
  30. data/doc/SDM/Cockroach.html +2 -2
  31. data/doc/SDM/DB2.html +2 -2
  32. data/doc/SDM/Druid.html +2 -2
  33. data/doc/SDM/DynamoDB.html +2 -2
  34. data/doc/SDM/Elastic.html +2 -2
  35. data/doc/SDM/ElasticacheRedis.html +2 -2
  36. data/doc/SDM/Gateway.html +2 -2
  37. data/doc/SDM/GoogleGKE.html +2 -2
  38. data/doc/SDM/Greenplum.html +2 -2
  39. data/doc/SDM/HTTPAuth.html +2 -2
  40. data/doc/SDM/HTTPBasicAuth.html +2 -2
  41. data/doc/SDM/HTTPNoAuth.html +2 -2
  42. data/doc/SDM/Kubernetes.html +2 -2
  43. data/doc/SDM/KubernetesBasicAuth.html +2 -2
  44. data/doc/SDM/KubernetesServiceAccount.html +2 -2
  45. data/doc/SDM/Maria.html +2 -2
  46. data/doc/SDM/Memcached.html +2 -2
  47. data/doc/SDM/Memsql.html +2 -2
  48. data/doc/SDM/MongoHost.html +2 -2
  49. data/doc/SDM/MongoLegacyHost.html +2 -2
  50. data/doc/SDM/MongoLegacyReplicaset.html +2 -2
  51. data/doc/SDM/MongoReplicaSet.html +2 -2
  52. data/doc/SDM/Mysql.html +2 -2
  53. data/doc/SDM/NodeCreateResponse.html +2 -2
  54. data/doc/SDM/NodeDeleteResponse.html +2 -2
  55. data/doc/SDM/NodeGetResponse.html +2 -2
  56. data/doc/SDM/NodeUpdateResponse.html +2 -2
  57. data/doc/SDM/Nodes.html +6 -6
  58. data/doc/SDM/Oracle.html +2 -2
  59. data/doc/SDM/Plumbing.html +349 -509
  60. data/doc/SDM/Postgres.html +2 -2
  61. data/doc/SDM/Presto.html +2 -2
  62. data/doc/SDM/RDP.html +2 -2
  63. data/doc/SDM/Redis.html +2 -2
  64. data/doc/SDM/Redshift.html +2 -2
  65. data/doc/SDM/Relay.html +2 -2
  66. data/doc/SDM/ResourceCreateResponse.html +2 -2
  67. data/doc/SDM/ResourceDeleteResponse.html +2 -2
  68. data/doc/SDM/ResourceGetResponse.html +2 -2
  69. data/doc/SDM/ResourceUpdateResponse.html +2 -2
  70. data/doc/SDM/Resources.html +6 -6
  71. data/doc/SDM/Role.html +2 -2
  72. data/doc/SDM/RoleAttachment.html +2 -2
  73. data/doc/SDM/RoleAttachmentCreateResponse.html +2 -2
  74. data/doc/SDM/RoleAttachmentDeleteResponse.html +2 -2
  75. data/doc/SDM/RoleAttachmentGetResponse.html +2 -2
  76. data/doc/SDM/RoleAttachments.html +5 -5
  77. data/doc/SDM/RoleCreateResponse.html +2 -2
  78. data/doc/SDM/RoleDeleteResponse.html +2 -2
  79. data/doc/SDM/RoleGetResponse.html +2 -2
  80. data/doc/SDM/RoleGrant.html +2 -2
  81. data/doc/SDM/RoleGrantCreateResponse.html +2 -2
  82. data/doc/SDM/RoleGrantDeleteResponse.html +2 -2
  83. data/doc/SDM/RoleGrantGetResponse.html +2 -2
  84. data/doc/SDM/RoleGrants.html +5 -5
  85. data/doc/SDM/RoleUpdateResponse.html +2 -2
  86. data/doc/SDM/Roles.html +6 -6
  87. data/doc/SDM/SQLServer.html +2 -2
  88. data/doc/SDM/SSH.html +2 -2
  89. data/doc/SDM/SSHCert.html +2 -2
  90. data/doc/SDM/Service.html +2 -2
  91. data/doc/SDM/Snowflake.html +2 -2
  92. data/doc/SDM/Sybase.html +2 -2
  93. data/doc/SDM/SybaseIQ.html +2 -2
  94. data/doc/SDM/Teradata.html +2 -2
  95. data/doc/SDM/User.html +2 -2
  96. data/doc/V1.html +0 -5
  97. data/doc/created.rid +38 -36
  98. data/doc/index.html +0 -2
  99. data/doc/js/search_index.js +1 -1
  100. data/doc/js/search_index.js.gz +0 -0
  101. data/doc/lib/version.html +1 -1
  102. data/doc/table_of_contents.html +118 -143
  103. data/examples/ldap-sync/ldapSync.rb +290 -0
  104. data/lib/grpc/account_attachments_pb.rb +0 -5
  105. data/lib/grpc/plumbing.rb +0 -34
  106. data/lib/models/porcelain.rb +0 -23
  107. data/lib/svc.rb +0 -2
  108. data/lib/version +1 -1
  109. data/lib/version.rb +1 -1
  110. metadata +17 -15
@@ -0,0 +1,290 @@
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
@@ -26,10 +26,6 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
26
26
  add_message "v1.AccountAttachmentCreateRequest" do
27
27
  optional :meta, :message, 1, "v1.CreateRequestMetadata"
28
28
  optional :account_attachment, :message, 2, "v1.AccountAttachment"
29
- optional :options, :message, 3, "v1.AccountAttachmentCreateOptions"
30
- end
31
- add_message "v1.AccountAttachmentCreateOptions" do
32
- optional :overwrite, :bool, 1
33
29
  end
34
30
  add_message "v1.AccountAttachmentCreateResponse" do
35
31
  optional :meta, :message, 1, "v1.CreateResponseMetadata"
@@ -72,7 +68,6 @@ end
72
68
 
73
69
  module V1
74
70
  AccountAttachmentCreateRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AccountAttachmentCreateRequest").msgclass
75
- AccountAttachmentCreateOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AccountAttachmentCreateOptions").msgclass
76
71
  AccountAttachmentCreateResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AccountAttachmentCreateResponse").msgclass
77
72
  AccountAttachmentGetRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AccountAttachmentGetRequest").msgclass
78
73
  AccountAttachmentGetResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.AccountAttachmentGetResponse").msgclass
@@ -258,40 +258,6 @@ module SDM
258
258
  end
259
259
  items
260
260
  end
261
- def self.convert_account_attachment_create_options_to_porcelain(plumbing)
262
- if plumbing == nil
263
- return nil
264
- end
265
- porcelain = AccountAttachmentCreateOptions.new()
266
- porcelain.overwrite = (plumbing.overwrite)
267
- porcelain
268
- end
269
-
270
- def self.convert_account_attachment_create_options_to_plumbing(porcelain)
271
- if porcelain == nil
272
- return nil
273
- end
274
- plumbing = V1::AccountAttachmentCreateOptions.new()
275
- plumbing.overwrite = (porcelain.overwrite) unless porcelain.overwrite == nil
276
- plumbing
277
- end
278
- def self.convert_repeated_account_attachment_create_options_to_plumbing(porcelains)
279
- items = Array.new
280
- porcelains.each do |porcelain|
281
- plumbing = convert_account_attachment_create_options_to_plumbing(porcelain)
282
- items.append(plumbing)
283
- end
284
- items
285
- end
286
-
287
- def self.convert_repeated_account_attachment_create_options_to_porcelain(plumbings)
288
- items = Array.new
289
- plumbings.each do |plumbing|
290
- porcelain = convert_account_attachment_create_options_to_porcelain(plumbing)
291
- items.append(porcelain)
292
- end
293
- items
294
- end
295
261
  def self.convert_account_attachment_create_response_to_porcelain(plumbing)
296
262
  if plumbing == nil
297
263
  return nil
@@ -115,29 +115,6 @@ module SDM
115
115
  end
116
116
  end
117
117
 
118
- # AccountAttachmentCreateOptions specifies extra options for creating an
119
- # AccountAttachment.
120
- class AccountAttachmentCreateOptions
121
- # Overwrite clears all account grants before the attachment.
122
- attr_accessor :overwrite
123
-
124
- def initialize(
125
- overwrite: nil
126
- )
127
- if overwrite != nil
128
- @overwrite = overwrite
129
- end
130
- end
131
-
132
- def to_json(options = {})
133
- hash = {}
134
- self.instance_variables.each do |var|
135
- hash[var.id2name.delete_prefix("@")] = self.instance_variable_get var
136
- end
137
- hash.to_json
138
- end
139
- end
140
-
141
118
  # AccountAttachmentCreateResponse reports how the AccountAttachments were created in the system.
142
119
  class AccountAttachmentCreateResponse
143
120
  # Reserved for future use.
data/lib/svc.rb CHANGED
@@ -43,13 +43,11 @@ module SDM
43
43
  # Create registers a new AccountAttachment.
44
44
  def create(
45
45
  account_attachment,
46
- options: nil,
47
46
  deadline: nil
48
47
  )
49
48
  req = V1::AccountAttachmentCreateRequest.new()
50
49
 
51
50
  req.account_attachment = Plumbing::convert_account_attachment_to_plumbing(account_attachment)
52
- req.options = Plumbing::convert_account_attachment_create_options_to_plumbing(options)
53
51
  tries = 0
54
52
  plumbing_response = nil
55
53
  loop do
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
  #
15
15
  module SDM
16
- VERSION = "1.0.5"
16
+ VERSION = "1.0.7"
17
17
  end
@@ -13,5 +13,5 @@
13
13
  # limitations under the License.
14
14
  #
15
15
  module SDM
16
- VERSION = "1.0.5"
16
+ VERSION = "1.0.7"
17
17
  end
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.5
4
+ version: 1.0.7
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-09 00:00:00.000000000 Z
11
+ date: 2020-06-12 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.
@@ -267,6 +267,7 @@ files:
267
267
  - examples/Gemfile
268
268
  - examples/Gemfile.lock
269
269
  - examples/README.md
270
+ - examples/ldap-sync/ldapSync.rb
270
271
  - examples/listUsers.rb
271
272
  - examples/okta-sync/Gemfile
272
273
  - examples/okta-sync/Gemfile.lock
@@ -321,7 +322,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
321
322
  - !ruby/object:Gem::Version
322
323
  version: 1.3.6
323
324
  requirements: []
324
- rubygems_version: 3.0.3
325
+ rubyforge_project:
326
+ rubygems_version: 2.7.6
325
327
  signing_key:
326
328
  specification_version: 4
327
329
  summary: strongDM SDK for the Ruby programming language.