strongdm 3.6.1__zip → 3.7.0__zip

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 (83) hide show
  1. {strongdm-3.6.1 → strongdm-3.7.0}/PKG-INFO +2 -2
  2. {strongdm-3.6.1 → strongdm-3.7.0}/setup.py +2 -2
  3. strongdm-3.7.0/strongdm/account_attachments_history_pb2.py +96 -0
  4. strongdm-3.7.0/strongdm/account_attachments_history_pb2_grpc.py +84 -0
  5. strongdm-3.7.0/strongdm/account_grants_history_pb2.py +96 -0
  6. strongdm-3.7.0/strongdm/account_grants_history_pb2_grpc.py +84 -0
  7. strongdm-3.7.0/strongdm/account_permissions_pb2.py +97 -0
  8. strongdm-3.7.0/strongdm/account_permissions_pb2_grpc.py +87 -0
  9. strongdm-3.7.0/strongdm/account_resources_pb2.py +99 -0
  10. strongdm-3.7.0/strongdm/account_resources_pb2_grpc.py +87 -0
  11. strongdm-3.7.0/strongdm/accounts_history_pb2.py +96 -0
  12. strongdm-3.7.0/strongdm/accounts_history_pb2_grpc.py +84 -0
  13. strongdm-3.7.0/strongdm/activities_pb2.py +177 -0
  14. strongdm-3.7.0/strongdm/activities_pb2_grpc.py +124 -0
  15. strongdm-3.7.0/strongdm/client.py +432 -0
  16. strongdm-3.7.0/strongdm/constants.py +377 -0
  17. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/drivers_pb2.py +6 -6
  18. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/models.py +1872 -132
  19. strongdm-3.7.0/strongdm/nodes_history_pb2.py +96 -0
  20. strongdm-3.7.0/strongdm/nodes_history_pb2_grpc.py +84 -0
  21. strongdm-3.7.0/strongdm/organization_history_pb2.py +154 -0
  22. strongdm-3.7.0/strongdm/organization_history_pb2_grpc.py +84 -0
  23. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/plumbing.py +935 -0
  24. strongdm-3.7.0/strongdm/queries_pb2.py +133 -0
  25. strongdm-3.7.0/strongdm/queries_pb2_grpc.py +90 -0
  26. strongdm-3.7.0/strongdm/remote_identities_history_pb2.py +96 -0
  27. strongdm-3.7.0/strongdm/remote_identities_history_pb2_grpc.py +84 -0
  28. strongdm-3.7.0/strongdm/remote_identity_groups_history_pb2.py +96 -0
  29. strongdm-3.7.0/strongdm/remote_identity_groups_history_pb2_grpc.py +84 -0
  30. strongdm-3.7.0/strongdm/replays_pb2.py +107 -0
  31. strongdm-3.7.0/strongdm/replays_pb2_grpc.py +87 -0
  32. strongdm-3.7.0/strongdm/resources_history_pb2.py +96 -0
  33. strongdm-3.7.0/strongdm/resources_history_pb2_grpc.py +84 -0
  34. strongdm-3.7.0/strongdm/role_resources_history_pb2.py +96 -0
  35. strongdm-3.7.0/strongdm/role_resources_history_pb2_grpc.py +84 -0
  36. strongdm-3.7.0/strongdm/role_resources_pb2.py +93 -0
  37. strongdm-3.7.0/strongdm/role_resources_pb2_grpc.py +87 -0
  38. strongdm-3.7.0/strongdm/roles_history_pb2.py +96 -0
  39. strongdm-3.7.0/strongdm/roles_history_pb2_grpc.py +84 -0
  40. strongdm-3.7.0/strongdm/secret_stores_history_pb2.py +96 -0
  41. strongdm-3.7.0/strongdm/secret_stores_history_pb2_grpc.py +84 -0
  42. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/svc.py +1199 -12
  43. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm.egg-info/PKG-INFO +2 -2
  44. strongdm-3.7.0/strongdm.egg-info/SOURCES.txt +78 -0
  45. strongdm-3.6.1/strongdm/client.py +0 -199
  46. strongdm-3.6.1/strongdm/constants.py +0 -66
  47. strongdm-3.6.1/strongdm.egg-info/SOURCES.txt +0 -44
  48. {strongdm-3.6.1 → strongdm-3.7.0}/README.md +0 -0
  49. {strongdm-3.6.1 → strongdm-3.7.0}/setup.cfg +0 -0
  50. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/__init__.py +0 -0
  51. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/account_attachments_pb2.py +0 -0
  52. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/account_attachments_pb2_grpc.py +0 -0
  53. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/account_grants_pb2.py +0 -0
  54. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/account_grants_pb2_grpc.py +0 -0
  55. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/accounts_pb2.py +0 -0
  56. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/accounts_pb2_grpc.py +0 -0
  57. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/control_panel_pb2.py +0 -0
  58. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/control_panel_pb2_grpc.py +0 -0
  59. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/drivers_pb2_grpc.py +0 -0
  60. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/errors.py +0 -0
  61. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/nodes_pb2.py +0 -0
  62. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/nodes_pb2_grpc.py +0 -0
  63. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/options_pb2.py +0 -0
  64. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/options_pb2_grpc.py +0 -0
  65. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/remote_identities_pb2.py +0 -0
  66. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/remote_identities_pb2_grpc.py +0 -0
  67. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/remote_identity_groups_pb2.py +0 -0
  68. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/remote_identity_groups_pb2_grpc.py +0 -0
  69. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/resources_pb2.py +0 -0
  70. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/resources_pb2_grpc.py +0 -0
  71. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/roles_pb2.py +0 -0
  72. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/roles_pb2_grpc.py +0 -0
  73. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/secret_store_types_pb2.py +0 -0
  74. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/secret_store_types_pb2_grpc.py +0 -0
  75. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/secret_stores_pb2.py +0 -0
  76. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/secret_stores_pb2_grpc.py +0 -0
  77. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/spec_pb2.py +0 -0
  78. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/spec_pb2_grpc.py +0 -0
  79. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/tags_pb2.py +0 -0
  80. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm/tags_pb2_grpc.py +0 -0
  81. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm.egg-info/dependency_links.txt +0 -0
  82. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm.egg-info/requires.txt +0 -0
  83. {strongdm-3.6.1 → strongdm-3.7.0}/strongdm.egg-info/top_level.txt +0 -0
@@ -24,30 +24,64 @@ from .spec_pb2 import *
24
24
  from .spec_pb2_grpc import *
25
25
  from .account_attachments_pb2 import *
26
26
  from .account_attachments_pb2_grpc import *
27
+ from .account_attachments_history_pb2 import *
28
+ from .account_attachments_history_pb2_grpc import *
27
29
  from .account_grants_pb2 import *
28
30
  from .account_grants_pb2_grpc import *
31
+ from .account_grants_history_pb2 import *
32
+ from .account_grants_history_pb2_grpc import *
33
+ from .account_permissions_pb2 import *
34
+ from .account_permissions_pb2_grpc import *
35
+ from .account_resources_pb2 import *
36
+ from .account_resources_pb2_grpc import *
29
37
  from .tags_pb2 import *
30
38
  from .tags_pb2_grpc import *
31
39
  from .accounts_pb2 import *
32
40
  from .accounts_pb2_grpc import *
41
+ from .accounts_history_pb2 import *
42
+ from .accounts_history_pb2_grpc import *
43
+ from .activities_pb2 import *
44
+ from .activities_pb2_grpc import *
33
45
  from .control_panel_pb2 import *
34
46
  from .control_panel_pb2_grpc import *
35
47
  from .drivers_pb2 import *
36
48
  from .drivers_pb2_grpc import *
37
49
  from .nodes_pb2 import *
38
50
  from .nodes_pb2_grpc import *
51
+ from .nodes_history_pb2 import *
52
+ from .nodes_history_pb2_grpc import *
53
+ from .organization_history_pb2 import *
54
+ from .organization_history_pb2_grpc import *
55
+ from .queries_pb2 import *
56
+ from .queries_pb2_grpc import *
39
57
  from .remote_identities_pb2 import *
40
58
  from .remote_identities_pb2_grpc import *
59
+ from .remote_identities_history_pb2 import *
60
+ from .remote_identities_history_pb2_grpc import *
41
61
  from .remote_identity_groups_pb2 import *
42
62
  from .remote_identity_groups_pb2_grpc import *
63
+ from .remote_identity_groups_history_pb2 import *
64
+ from .remote_identity_groups_history_pb2_grpc import *
65
+ from .replays_pb2 import *
66
+ from .replays_pb2_grpc import *
43
67
  from .resources_pb2 import *
44
68
  from .resources_pb2_grpc import *
69
+ from .resources_history_pb2 import *
70
+ from .resources_history_pb2_grpc import *
71
+ from .role_resources_pb2 import *
72
+ from .role_resources_pb2_grpc import *
73
+ from .role_resources_history_pb2 import *
74
+ from .role_resources_history_pb2_grpc import *
45
75
  from .roles_pb2 import *
46
76
  from .roles_pb2_grpc import *
77
+ from .roles_history_pb2 import *
78
+ from .roles_history_pb2_grpc import *
47
79
  from .secret_store_types_pb2 import *
48
80
  from .secret_store_types_pb2_grpc import *
49
81
  from .secret_stores_pb2 import *
50
82
  from .secret_stores_pb2_grpc import *
83
+ from .secret_stores_history_pb2 import *
84
+ from .secret_stores_history_pb2_grpc import *
51
85
  import warnings
52
86
  import functools
53
87
 
@@ -116,6 +150,9 @@ class AccountAttachments:
116
150
  Get reads one AccountAttachment by ID.
117
151
  '''
118
152
  req = AccountAttachmentGetRequest()
153
+ if self.parent.snapshot_datetime is not None:
154
+ req.meta.CopyFrom(GetRequestMetadata())
155
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
119
156
 
120
157
  req.id = (id)
121
158
  tries = 0
@@ -184,6 +221,8 @@ class AccountAttachments:
184
221
  page_size_option = self.parent._test_options.get('PageSize')
185
222
  if isinstance(page_size_option, int):
186
223
  req.meta.limit = page_size_option
224
+ if self.parent.snapshot_datetime is not None:
225
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
187
226
 
188
227
  req.filter = plumbing.quote_filter_args(filter, *args)
189
228
 
@@ -213,6 +252,76 @@ class AccountAttachments:
213
252
  return generator(self, req)
214
253
 
215
254
 
255
+ class SnapshotAccountAttachments:
256
+ '''
257
+ SnapshotAccountAttachments exposes the read only methods of the AccountAttachments
258
+ service for historical queries.
259
+ '''
260
+ def __init__(self, account_attachments):
261
+ self.account_attachments = account_attachments
262
+
263
+ def get(self, id, timeout=None):
264
+ '''
265
+ Get reads one AccountAttachment by ID.
266
+ '''
267
+ return self.account_attachments.get(id, timeout=timeout)
268
+
269
+ def list(self, filter, *args, timeout=None):
270
+ '''
271
+ List gets a list of AccountAttachments matching a given set of criteria.
272
+ '''
273
+ return self.account_attachments.list(filter, *args, timeout=timeout)
274
+
275
+
276
+ class AccountAttachmentsHistory:
277
+ '''
278
+ AccountAttachmentsHistory records all changes to the state of an AccountAttachment.
279
+ See `strongdm.models.AccountAttachmentHistory`.
280
+ '''
281
+ def __init__(self, channel, client):
282
+ self.parent = client
283
+ self.stub = AccountAttachmentsHistoryStub(channel)
284
+
285
+ def list(self, filter, *args, timeout=None):
286
+ '''
287
+ List gets a list of AccountAttachmentHistory records matching a given set of criteria.
288
+ '''
289
+ req = AccountAttachmentHistoryListRequest()
290
+ req.meta.CopyFrom(ListRequestMetadata())
291
+ page_size_option = self.parent._test_options.get('PageSize')
292
+ if isinstance(page_size_option, int):
293
+ req.meta.limit = page_size_option
294
+ if self.parent.snapshot_datetime is not None:
295
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
296
+
297
+ req.filter = plumbing.quote_filter_args(filter, *args)
298
+
299
+ def generator(svc, req):
300
+ tries = 0
301
+ while True:
302
+ try:
303
+ plumbing_response = svc.stub.List(
304
+ req,
305
+ metadata=svc.parent.get_metadata(
306
+ 'AccountAttachmentsHistory.List', req),
307
+ timeout=timeout)
308
+ except Exception as e:
309
+ if self.parent.shouldRetry(tries, e):
310
+ tries += 1
311
+ self.parent.jitterSleep(tries)
312
+ continue
313
+ raise plumbing.convert_error_to_porcelain(e) from e
314
+ tries = 0
315
+ for plumbing_item in plumbing_response.history:
316
+ yield plumbing.convert_account_attachment_history_to_porcelain(
317
+ plumbing_item)
318
+ if plumbing_response.meta.next_cursor == '':
319
+ break
320
+ req.meta.cursor = plumbing_response.meta.next_cursor
321
+
322
+ return generator(self, req)
323
+
324
+
216
325
  class AccountGrants:
217
326
  '''
218
327
  AccountGrants assign a resource directly to an account, giving the account the permission to connect to that resource.
@@ -262,6 +371,9 @@ class AccountGrants:
262
371
  Get reads one AccountGrant by ID.
263
372
  '''
264
373
  req = AccountGrantGetRequest()
374
+ if self.parent.snapshot_datetime is not None:
375
+ req.meta.CopyFrom(GetRequestMetadata())
376
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
265
377
 
266
378
  req.id = (id)
267
379
  tries = 0
@@ -330,6 +442,8 @@ class AccountGrants:
330
442
  page_size_option = self.parent._test_options.get('PageSize')
331
443
  if isinstance(page_size_option, int):
332
444
  req.meta.limit = page_size_option
445
+ if self.parent.snapshot_datetime is not None:
446
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
333
447
 
334
448
  req.filter = plumbing.quote_filter_args(filter, *args)
335
449
 
@@ -359,6 +473,206 @@ class AccountGrants:
359
473
  return generator(self, req)
360
474
 
361
475
 
476
+ class SnapshotAccountGrants:
477
+ '''
478
+ SnapshotAccountGrants exposes the read only methods of the AccountGrants
479
+ service for historical queries.
480
+ '''
481
+ def __init__(self, account_grants):
482
+ self.account_grants = account_grants
483
+
484
+ def get(self, id, timeout=None):
485
+ '''
486
+ Get reads one AccountGrant by ID.
487
+ '''
488
+ return self.account_grants.get(id, timeout=timeout)
489
+
490
+ def list(self, filter, *args, timeout=None):
491
+ '''
492
+ List gets a list of AccountGrants matching a given set of criteria.
493
+ '''
494
+ return self.account_grants.list(filter, *args, timeout=timeout)
495
+
496
+
497
+ class AccountGrantsHistory:
498
+ '''
499
+ AccountGrantsHistory records all changes to the state of an AccountGrant.
500
+ See `strongdm.models.AccountGrantHistory`.
501
+ '''
502
+ def __init__(self, channel, client):
503
+ self.parent = client
504
+ self.stub = AccountGrantsHistoryStub(channel)
505
+
506
+ def list(self, filter, *args, timeout=None):
507
+ '''
508
+ List gets a list of AccountGrantHistory records matching a given set of criteria.
509
+ '''
510
+ req = AccountGrantHistoryListRequest()
511
+ req.meta.CopyFrom(ListRequestMetadata())
512
+ page_size_option = self.parent._test_options.get('PageSize')
513
+ if isinstance(page_size_option, int):
514
+ req.meta.limit = page_size_option
515
+ if self.parent.snapshot_datetime is not None:
516
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
517
+
518
+ req.filter = plumbing.quote_filter_args(filter, *args)
519
+
520
+ def generator(svc, req):
521
+ tries = 0
522
+ while True:
523
+ try:
524
+ plumbing_response = svc.stub.List(
525
+ req,
526
+ metadata=svc.parent.get_metadata(
527
+ 'AccountGrantsHistory.List', req),
528
+ timeout=timeout)
529
+ except Exception as e:
530
+ if self.parent.shouldRetry(tries, e):
531
+ tries += 1
532
+ self.parent.jitterSleep(tries)
533
+ continue
534
+ raise plumbing.convert_error_to_porcelain(e) from e
535
+ tries = 0
536
+ for plumbing_item in plumbing_response.history:
537
+ yield plumbing.convert_account_grant_history_to_porcelain(
538
+ plumbing_item)
539
+ if plumbing_response.meta.next_cursor == '':
540
+ break
541
+ req.meta.cursor = plumbing_response.meta.next_cursor
542
+
543
+ return generator(self, req)
544
+
545
+
546
+ class AccountPermissions:
547
+ '''
548
+ AccountPermissions records the granular permissions accounts have, allowing them to execute
549
+ relevant commands via StrongDM's APIs.
550
+ See `strongdm.models.AccountPermission`.
551
+ '''
552
+ def __init__(self, channel, client):
553
+ self.parent = client
554
+ self.stub = AccountPermissionsStub(channel)
555
+
556
+ def list(self, filter, *args, timeout=None):
557
+ '''
558
+ List gets a list of Permission records matching a given set of criteria.
559
+ '''
560
+ req = AccountPermissionListRequest()
561
+ req.meta.CopyFrom(ListRequestMetadata())
562
+ page_size_option = self.parent._test_options.get('PageSize')
563
+ if isinstance(page_size_option, int):
564
+ req.meta.limit = page_size_option
565
+ if self.parent.snapshot_datetime is not None:
566
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
567
+
568
+ req.filter = plumbing.quote_filter_args(filter, *args)
569
+
570
+ def generator(svc, req):
571
+ tries = 0
572
+ while True:
573
+ try:
574
+ plumbing_response = svc.stub.List(
575
+ req,
576
+ metadata=svc.parent.get_metadata(
577
+ 'AccountPermissions.List', req),
578
+ timeout=timeout)
579
+ except Exception as e:
580
+ if self.parent.shouldRetry(tries, e):
581
+ tries += 1
582
+ self.parent.jitterSleep(tries)
583
+ continue
584
+ raise plumbing.convert_error_to_porcelain(e) from e
585
+ tries = 0
586
+ for plumbing_item in plumbing_response.permissions:
587
+ yield plumbing.convert_account_permission_to_porcelain(
588
+ plumbing_item)
589
+ if plumbing_response.meta.next_cursor == '':
590
+ break
591
+ req.meta.cursor = plumbing_response.meta.next_cursor
592
+
593
+ return generator(self, req)
594
+
595
+
596
+ class SnapshotAccountPermissions:
597
+ '''
598
+ SnapshotAccountPermissions exposes the read only methods of the AccountPermissions
599
+ service for historical queries.
600
+ '''
601
+ def __init__(self, account_permissions):
602
+ self.account_permissions = account_permissions
603
+
604
+ def list(self, filter, *args, timeout=None):
605
+ '''
606
+ List gets a list of Permission records matching a given set of criteria.
607
+ '''
608
+ return self.account_permissions.list(filter, *args, timeout=timeout)
609
+
610
+
611
+ class AccountResources:
612
+ '''
613
+ AccountResources enumerates the resources to which accounts have access.
614
+ The AccountResources service is read-only.
615
+ See `strongdm.models.AccountResource`.
616
+ '''
617
+ def __init__(self, channel, client):
618
+ self.parent = client
619
+ self.stub = AccountResourcesStub(channel)
620
+
621
+ def list(self, filter, *args, timeout=None):
622
+ '''
623
+ List gets a list of AccountResource records matching a given set of criteria.
624
+ '''
625
+ req = AccountResourceListRequest()
626
+ req.meta.CopyFrom(ListRequestMetadata())
627
+ page_size_option = self.parent._test_options.get('PageSize')
628
+ if isinstance(page_size_option, int):
629
+ req.meta.limit = page_size_option
630
+ if self.parent.snapshot_datetime is not None:
631
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
632
+
633
+ req.filter = plumbing.quote_filter_args(filter, *args)
634
+
635
+ def generator(svc, req):
636
+ tries = 0
637
+ while True:
638
+ try:
639
+ plumbing_response = svc.stub.List(
640
+ req,
641
+ metadata=svc.parent.get_metadata(
642
+ 'AccountResources.List', req),
643
+ timeout=timeout)
644
+ except Exception as e:
645
+ if self.parent.shouldRetry(tries, e):
646
+ tries += 1
647
+ self.parent.jitterSleep(tries)
648
+ continue
649
+ raise plumbing.convert_error_to_porcelain(e) from e
650
+ tries = 0
651
+ for plumbing_item in plumbing_response.account_resources:
652
+ yield plumbing.convert_account_resource_to_porcelain(
653
+ plumbing_item)
654
+ if plumbing_response.meta.next_cursor == '':
655
+ break
656
+ req.meta.cursor = plumbing_response.meta.next_cursor
657
+
658
+ return generator(self, req)
659
+
660
+
661
+ class SnapshotAccountResources:
662
+ '''
663
+ SnapshotAccountResources exposes the read only methods of the AccountResources
664
+ service for historical queries.
665
+ '''
666
+ def __init__(self, account_resources):
667
+ self.account_resources = account_resources
668
+
669
+ def list(self, filter, *args, timeout=None):
670
+ '''
671
+ List gets a list of AccountResource records matching a given set of criteria.
672
+ '''
673
+ return self.account_resources.list(filter, *args, timeout=timeout)
674
+
675
+
362
676
  class Accounts:
363
677
  '''
364
678
  Accounts are users that have access to strongDM. There are two types of accounts:
@@ -411,6 +725,9 @@ class Accounts:
411
725
  Get reads one Account by ID.
412
726
  '''
413
727
  req = AccountGetRequest()
728
+ if self.parent.snapshot_datetime is not None:
729
+ req.meta.CopyFrom(GetRequestMetadata())
730
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
414
731
 
415
732
  req.id = (id)
416
733
  tries = 0
@@ -510,6 +827,8 @@ class Accounts:
510
827
  page_size_option = self.parent._test_options.get('PageSize')
511
828
  if isinstance(page_size_option, int):
512
829
  req.meta.limit = page_size_option
830
+ if self.parent.snapshot_datetime is not None:
831
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
513
832
 
514
833
  req.filter = plumbing.quote_filter_args(filter, *args)
515
834
 
@@ -537,19 +856,174 @@ class Accounts:
537
856
  return generator(self, req)
538
857
 
539
858
 
540
- class ControlPanel:
859
+ class SnapshotAccounts:
541
860
  '''
542
- ControlPanel contains all administrative controls.
861
+ SnapshotAccounts exposes the read only methods of the Accounts
862
+ service for historical queries.
863
+ '''
864
+ def __init__(self, accounts):
865
+ self.accounts = accounts
866
+
867
+ def get(self, id, timeout=None):
868
+ '''
869
+ Get reads one Account by ID.
870
+ '''
871
+ return self.accounts.get(id, timeout=timeout)
872
+
873
+ def list(self, filter, *args, timeout=None):
874
+ '''
875
+ List gets a list of Accounts matching a given set of criteria.
876
+ '''
877
+ return self.accounts.list(filter, *args, timeout=timeout)
878
+
879
+
880
+ class AccountsHistory:
881
+ '''
882
+ AccountsHistory records all changes to the state of an Account.
883
+ See `strongdm.models.AccountHistory`.
543
884
  '''
544
885
  def __init__(self, channel, client):
545
886
  self.parent = client
546
- self.stub = ControlPanelStub(channel)
887
+ self.stub = AccountsHistoryStub(channel)
547
888
 
548
- def get_sshca_public_key(self, timeout=None):
889
+ def list(self, filter, *args, timeout=None):
549
890
  '''
550
- GetSSHCAPublicKey retrieves the SSH CA public key.
891
+ List gets a list of AccountHistory records matching a given set of criteria.
551
892
  '''
552
- req = ControlPanelGetSSHCAPublicKeyRequest()
893
+ req = AccountHistoryListRequest()
894
+ req.meta.CopyFrom(ListRequestMetadata())
895
+ page_size_option = self.parent._test_options.get('PageSize')
896
+ if isinstance(page_size_option, int):
897
+ req.meta.limit = page_size_option
898
+ if self.parent.snapshot_datetime is not None:
899
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
900
+
901
+ req.filter = plumbing.quote_filter_args(filter, *args)
902
+
903
+ def generator(svc, req):
904
+ tries = 0
905
+ while True:
906
+ try:
907
+ plumbing_response = svc.stub.List(
908
+ req,
909
+ metadata=svc.parent.get_metadata(
910
+ 'AccountsHistory.List', req),
911
+ timeout=timeout)
912
+ except Exception as e:
913
+ if self.parent.shouldRetry(tries, e):
914
+ tries += 1
915
+ self.parent.jitterSleep(tries)
916
+ continue
917
+ raise plumbing.convert_error_to_porcelain(e) from e
918
+ tries = 0
919
+ for plumbing_item in plumbing_response.history:
920
+ yield plumbing.convert_account_history_to_porcelain(
921
+ plumbing_item)
922
+ if plumbing_response.meta.next_cursor == '':
923
+ break
924
+ req.meta.cursor = plumbing_response.meta.next_cursor
925
+
926
+ return generator(self, req)
927
+
928
+
929
+ class Activities:
930
+ '''
931
+ An Activity is a record of an action taken against a strongDM deployment, e.g.
932
+ a user creation, resource deletion, sso configuration change, etc. The Activities
933
+ service is read-only.
934
+ See `strongdm.models.Activity`.
935
+ '''
936
+ def __init__(self, channel, client):
937
+ self.parent = client
938
+ self.stub = ActivitiesStub(channel)
939
+
940
+ def get(self, id, timeout=None):
941
+ '''
942
+ Get reads one Activity by ID.
943
+ '''
944
+ req = ActivityGetRequest()
945
+ if self.parent.snapshot_datetime is not None:
946
+ req.meta.CopyFrom(GetRequestMetadata())
947
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
948
+
949
+ req.id = (id)
950
+ tries = 0
951
+ plumbing_response = None
952
+ while True:
953
+ try:
954
+ plumbing_response = self.stub.Get(
955
+ req,
956
+ metadata=self.parent.get_metadata('Activities.Get', req),
957
+ timeout=timeout)
958
+ except Exception as e:
959
+ if self.parent.shouldRetry(tries, e):
960
+ tries += 1
961
+ self.parent.jitterSleep(tries)
962
+ continue
963
+ raise plumbing.convert_error_to_porcelain(e) from e
964
+ break
965
+
966
+ resp = models.ActivityGetResponse()
967
+ resp.activity = plumbing.convert_activity_to_porcelain(
968
+ plumbing_response.activity)
969
+ resp.meta = plumbing.convert_get_response_metadata_to_porcelain(
970
+ plumbing_response.meta)
971
+ resp.rate_limit = plumbing.convert_rate_limit_metadata_to_porcelain(
972
+ plumbing_response.rate_limit)
973
+ return resp
974
+
975
+ def list(self, filter, *args, timeout=None):
976
+ '''
977
+ List gets a list of Activities matching a given set of criteria.
978
+ '''
979
+ req = ActivityListRequest()
980
+ req.meta.CopyFrom(ListRequestMetadata())
981
+ page_size_option = self.parent._test_options.get('PageSize')
982
+ if isinstance(page_size_option, int):
983
+ req.meta.limit = page_size_option
984
+ if self.parent.snapshot_datetime is not None:
985
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
986
+
987
+ req.filter = plumbing.quote_filter_args(filter, *args)
988
+
989
+ def generator(svc, req):
990
+ tries = 0
991
+ while True:
992
+ try:
993
+ plumbing_response = svc.stub.List(
994
+ req,
995
+ metadata=svc.parent.get_metadata(
996
+ 'Activities.List', req),
997
+ timeout=timeout)
998
+ except Exception as e:
999
+ if self.parent.shouldRetry(tries, e):
1000
+ tries += 1
1001
+ self.parent.jitterSleep(tries)
1002
+ continue
1003
+ raise plumbing.convert_error_to_porcelain(e) from e
1004
+ tries = 0
1005
+ for plumbing_item in plumbing_response.activities:
1006
+ yield plumbing.convert_activity_to_porcelain(plumbing_item)
1007
+ if plumbing_response.meta.next_cursor == '':
1008
+ break
1009
+ req.meta.cursor = plumbing_response.meta.next_cursor
1010
+
1011
+ return generator(self, req)
1012
+
1013
+
1014
+ class ControlPanel:
1015
+ '''
1016
+ ControlPanel contains all administrative controls.
1017
+ '''
1018
+ def __init__(self, channel, client):
1019
+ self.parent = client
1020
+ self.stub = ControlPanelStub(channel)
1021
+
1022
+ def get_sshca_public_key(self, timeout=None):
1023
+ '''
1024
+ GetSSHCAPublicKey retrieves the SSH CA public key.
1025
+ '''
1026
+ req = ControlPanelGetSSHCAPublicKeyRequest()
553
1027
 
554
1028
  tries = 0
555
1029
  plumbing_response = None
@@ -660,6 +1134,9 @@ class Nodes:
660
1134
  Get reads one Node by ID.
661
1135
  '''
662
1136
  req = NodeGetRequest()
1137
+ if self.parent.snapshot_datetime is not None:
1138
+ req.meta.CopyFrom(GetRequestMetadata())
1139
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
663
1140
 
664
1141
  req.id = (id)
665
1142
  tries = 0
@@ -757,6 +1234,8 @@ class Nodes:
757
1234
  page_size_option = self.parent._test_options.get('PageSize')
758
1235
  if isinstance(page_size_option, int):
759
1236
  req.meta.limit = page_size_option
1237
+ if self.parent.snapshot_datetime is not None:
1238
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
760
1239
 
761
1240
  req.filter = plumbing.quote_filter_args(filter, *args)
762
1241
 
@@ -784,6 +1263,174 @@ class Nodes:
784
1263
  return generator(self, req)
785
1264
 
786
1265
 
1266
+ class SnapshotNodes:
1267
+ '''
1268
+ SnapshotNodes exposes the read only methods of the Nodes
1269
+ service for historical queries.
1270
+ '''
1271
+ def __init__(self, nodes):
1272
+ self.nodes = nodes
1273
+
1274
+ def get(self, id, timeout=None):
1275
+ '''
1276
+ Get reads one Node by ID.
1277
+ '''
1278
+ return self.nodes.get(id, timeout=timeout)
1279
+
1280
+ def list(self, filter, *args, timeout=None):
1281
+ '''
1282
+ List gets a list of Nodes matching a given set of criteria.
1283
+ '''
1284
+ return self.nodes.list(filter, *args, timeout=timeout)
1285
+
1286
+
1287
+ class NodesHistory:
1288
+ '''
1289
+ NodesHistory records all changes to the state of a Node.
1290
+ See `strongdm.models.NodeHistory`.
1291
+ '''
1292
+ def __init__(self, channel, client):
1293
+ self.parent = client
1294
+ self.stub = NodesHistoryStub(channel)
1295
+
1296
+ def list(self, filter, *args, timeout=None):
1297
+ '''
1298
+ List gets a list of NodeHistory records matching a given set of criteria.
1299
+ '''
1300
+ req = NodeHistoryListRequest()
1301
+ req.meta.CopyFrom(ListRequestMetadata())
1302
+ page_size_option = self.parent._test_options.get('PageSize')
1303
+ if isinstance(page_size_option, int):
1304
+ req.meta.limit = page_size_option
1305
+ if self.parent.snapshot_datetime is not None:
1306
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1307
+
1308
+ req.filter = plumbing.quote_filter_args(filter, *args)
1309
+
1310
+ def generator(svc, req):
1311
+ tries = 0
1312
+ while True:
1313
+ try:
1314
+ plumbing_response = svc.stub.List(
1315
+ req,
1316
+ metadata=svc.parent.get_metadata(
1317
+ 'NodesHistory.List', req),
1318
+ timeout=timeout)
1319
+ except Exception as e:
1320
+ if self.parent.shouldRetry(tries, e):
1321
+ tries += 1
1322
+ self.parent.jitterSleep(tries)
1323
+ continue
1324
+ raise plumbing.convert_error_to_porcelain(e) from e
1325
+ tries = 0
1326
+ for plumbing_item in plumbing_response.history:
1327
+ yield plumbing.convert_node_history_to_porcelain(
1328
+ plumbing_item)
1329
+ if plumbing_response.meta.next_cursor == '':
1330
+ break
1331
+ req.meta.cursor = plumbing_response.meta.next_cursor
1332
+
1333
+ return generator(self, req)
1334
+
1335
+
1336
+ class OrganizationHistory:
1337
+ '''
1338
+ OrganizationHistory records all changes to the state of an Organization.
1339
+ See `strongdm.models.OrganizationHistoryRecord`.
1340
+ '''
1341
+ def __init__(self, channel, client):
1342
+ self.parent = client
1343
+ self.stub = OrganizationHistoryStub(channel)
1344
+
1345
+ def list(self, filter, *args, timeout=None):
1346
+ '''
1347
+ List gets a list of OrganizationHistory records matching a given set of criteria.
1348
+ '''
1349
+ req = OrganizationHistoryListRequest()
1350
+ req.meta.CopyFrom(ListRequestMetadata())
1351
+ page_size_option = self.parent._test_options.get('PageSize')
1352
+ if isinstance(page_size_option, int):
1353
+ req.meta.limit = page_size_option
1354
+ if self.parent.snapshot_datetime is not None:
1355
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1356
+
1357
+ req.filter = plumbing.quote_filter_args(filter, *args)
1358
+
1359
+ def generator(svc, req):
1360
+ tries = 0
1361
+ while True:
1362
+ try:
1363
+ plumbing_response = svc.stub.List(
1364
+ req,
1365
+ metadata=svc.parent.get_metadata(
1366
+ 'OrganizationHistory.List', req),
1367
+ timeout=timeout)
1368
+ except Exception as e:
1369
+ if self.parent.shouldRetry(tries, e):
1370
+ tries += 1
1371
+ self.parent.jitterSleep(tries)
1372
+ continue
1373
+ raise plumbing.convert_error_to_porcelain(e) from e
1374
+ tries = 0
1375
+ for plumbing_item in plumbing_response.history:
1376
+ yield plumbing.convert_organization_history_record_to_porcelain(
1377
+ plumbing_item)
1378
+ if plumbing_response.meta.next_cursor == '':
1379
+ break
1380
+ req.meta.cursor = plumbing_response.meta.next_cursor
1381
+
1382
+ return generator(self, req)
1383
+
1384
+
1385
+ class Queries:
1386
+ '''
1387
+ A Query is a record of a single client request to a resource, such as an SQL query.
1388
+ Long-running SSH, RDP, or Kubernetes interactive sessions also count as queries.
1389
+ The Queries service is read-only.
1390
+ See `strongdm.models.Query`.
1391
+ '''
1392
+ def __init__(self, channel, client):
1393
+ self.parent = client
1394
+ self.stub = QueriesStub(channel)
1395
+
1396
+ def list(self, filter, *args, timeout=None):
1397
+ '''
1398
+ List gets a list of Queries matching a given set of criteria.
1399
+ '''
1400
+ req = QueryListRequest()
1401
+ req.meta.CopyFrom(ListRequestMetadata())
1402
+ page_size_option = self.parent._test_options.get('PageSize')
1403
+ if isinstance(page_size_option, int):
1404
+ req.meta.limit = page_size_option
1405
+ if self.parent.snapshot_datetime is not None:
1406
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1407
+
1408
+ req.filter = plumbing.quote_filter_args(filter, *args)
1409
+
1410
+ def generator(svc, req):
1411
+ tries = 0
1412
+ while True:
1413
+ try:
1414
+ plumbing_response = svc.stub.List(
1415
+ req,
1416
+ metadata=svc.parent.get_metadata('Queries.List', req),
1417
+ timeout=timeout)
1418
+ except Exception as e:
1419
+ if self.parent.shouldRetry(tries, e):
1420
+ tries += 1
1421
+ self.parent.jitterSleep(tries)
1422
+ continue
1423
+ raise plumbing.convert_error_to_porcelain(e) from e
1424
+ tries = 0
1425
+ for plumbing_item in plumbing_response.queries:
1426
+ yield plumbing.convert_query_to_porcelain(plumbing_item)
1427
+ if plumbing_response.meta.next_cursor == '':
1428
+ break
1429
+ req.meta.cursor = plumbing_response.meta.next_cursor
1430
+
1431
+ return generator(self, req)
1432
+
1433
+
787
1434
  class RemoteIdentities:
788
1435
  '''
789
1436
  RemoteIdentities assign a resource directly to an account, giving the account the permission to connect to that resource.
@@ -833,6 +1480,9 @@ class RemoteIdentities:
833
1480
  Get reads one RemoteIdentity by ID.
834
1481
  '''
835
1482
  req = RemoteIdentityGetRequest()
1483
+ if self.parent.snapshot_datetime is not None:
1484
+ req.meta.CopyFrom(GetRequestMetadata())
1485
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
836
1486
 
837
1487
  req.id = (id)
838
1488
  tries = 0
@@ -936,6 +1586,8 @@ class RemoteIdentities:
936
1586
  page_size_option = self.parent._test_options.get('PageSize')
937
1587
  if isinstance(page_size_option, int):
938
1588
  req.meta.limit = page_size_option
1589
+ if self.parent.snapshot_datetime is not None:
1590
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
939
1591
 
940
1592
  req.filter = plumbing.quote_filter_args(filter, *args)
941
1593
 
@@ -965,6 +1617,76 @@ class RemoteIdentities:
965
1617
  return generator(self, req)
966
1618
 
967
1619
 
1620
+ class SnapshotRemoteIdentities:
1621
+ '''
1622
+ SnapshotRemoteIdentities exposes the read only methods of the RemoteIdentities
1623
+ service for historical queries.
1624
+ '''
1625
+ def __init__(self, remote_identities):
1626
+ self.remote_identities = remote_identities
1627
+
1628
+ def get(self, id, timeout=None):
1629
+ '''
1630
+ Get reads one RemoteIdentity by ID.
1631
+ '''
1632
+ return self.remote_identities.get(id, timeout=timeout)
1633
+
1634
+ def list(self, filter, *args, timeout=None):
1635
+ '''
1636
+ List gets a list of RemoteIdentities matching a given set of criteria.
1637
+ '''
1638
+ return self.remote_identities.list(filter, *args, timeout=timeout)
1639
+
1640
+
1641
+ class RemoteIdentitiesHistory:
1642
+ '''
1643
+ RemoteIdentitiesHistory records all changes to the state of a RemoteIdentity.
1644
+ See `strongdm.models.RemoteIdentityHistory`.
1645
+ '''
1646
+ def __init__(self, channel, client):
1647
+ self.parent = client
1648
+ self.stub = RemoteIdentitiesHistoryStub(channel)
1649
+
1650
+ def list(self, filter, *args, timeout=None):
1651
+ '''
1652
+ List gets a list of RemoteIdentityHistory records matching a given set of criteria.
1653
+ '''
1654
+ req = RemoteIdentityHistoryListRequest()
1655
+ req.meta.CopyFrom(ListRequestMetadata())
1656
+ page_size_option = self.parent._test_options.get('PageSize')
1657
+ if isinstance(page_size_option, int):
1658
+ req.meta.limit = page_size_option
1659
+ if self.parent.snapshot_datetime is not None:
1660
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1661
+
1662
+ req.filter = plumbing.quote_filter_args(filter, *args)
1663
+
1664
+ def generator(svc, req):
1665
+ tries = 0
1666
+ while True:
1667
+ try:
1668
+ plumbing_response = svc.stub.List(
1669
+ req,
1670
+ metadata=svc.parent.get_metadata(
1671
+ 'RemoteIdentitiesHistory.List', req),
1672
+ timeout=timeout)
1673
+ except Exception as e:
1674
+ if self.parent.shouldRetry(tries, e):
1675
+ tries += 1
1676
+ self.parent.jitterSleep(tries)
1677
+ continue
1678
+ raise plumbing.convert_error_to_porcelain(e) from e
1679
+ tries = 0
1680
+ for plumbing_item in plumbing_response.history:
1681
+ yield plumbing.convert_remote_identity_history_to_porcelain(
1682
+ plumbing_item)
1683
+ if plumbing_response.meta.next_cursor == '':
1684
+ break
1685
+ req.meta.cursor = plumbing_response.meta.next_cursor
1686
+
1687
+ return generator(self, req)
1688
+
1689
+
968
1690
  class RemoteIdentityGroups:
969
1691
  '''
970
1692
  A RemoteIdentityGroup is a named grouping of Remote Identities for Accounts.
@@ -980,6 +1702,9 @@ class RemoteIdentityGroups:
980
1702
  Get reads one RemoteIdentityGroup by ID.
981
1703
  '''
982
1704
  req = RemoteIdentityGroupGetRequest()
1705
+ if self.parent.snapshot_datetime is not None:
1706
+ req.meta.CopyFrom(GetRequestMetadata())
1707
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
983
1708
 
984
1709
  req.id = (id)
985
1710
  tries = 0
@@ -1010,13 +1735,135 @@ class RemoteIdentityGroups:
1010
1735
 
1011
1736
  def list(self, filter, *args, timeout=None):
1012
1737
  '''
1013
- List gets a list of RemoteIdentityGroups matching a given set of criteria.
1738
+ List gets a list of RemoteIdentityGroups matching a given set of criteria.
1739
+ '''
1740
+ req = RemoteIdentityGroupListRequest()
1741
+ req.meta.CopyFrom(ListRequestMetadata())
1742
+ page_size_option = self.parent._test_options.get('PageSize')
1743
+ if isinstance(page_size_option, int):
1744
+ req.meta.limit = page_size_option
1745
+ if self.parent.snapshot_datetime is not None:
1746
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1747
+
1748
+ req.filter = plumbing.quote_filter_args(filter, *args)
1749
+
1750
+ def generator(svc, req):
1751
+ tries = 0
1752
+ while True:
1753
+ try:
1754
+ plumbing_response = svc.stub.List(
1755
+ req,
1756
+ metadata=svc.parent.get_metadata(
1757
+ 'RemoteIdentityGroups.List', req),
1758
+ timeout=timeout)
1759
+ except Exception as e:
1760
+ if self.parent.shouldRetry(tries, e):
1761
+ tries += 1
1762
+ self.parent.jitterSleep(tries)
1763
+ continue
1764
+ raise plumbing.convert_error_to_porcelain(e) from e
1765
+ tries = 0
1766
+ for plumbing_item in plumbing_response.remote_identity_groups:
1767
+ yield plumbing.convert_remote_identity_group_to_porcelain(
1768
+ plumbing_item)
1769
+ if plumbing_response.meta.next_cursor == '':
1770
+ break
1771
+ req.meta.cursor = plumbing_response.meta.next_cursor
1772
+
1773
+ return generator(self, req)
1774
+
1775
+
1776
+ class SnapshotRemoteIdentityGroups:
1777
+ '''
1778
+ SnapshotRemoteIdentityGroups exposes the read only methods of the RemoteIdentityGroups
1779
+ service for historical queries.
1780
+ '''
1781
+ def __init__(self, remote_identity_groups):
1782
+ self.remote_identity_groups = remote_identity_groups
1783
+
1784
+ def get(self, id, timeout=None):
1785
+ '''
1786
+ Get reads one RemoteIdentityGroup by ID.
1787
+ '''
1788
+ return self.remote_identity_groups.get(id, timeout=timeout)
1789
+
1790
+ def list(self, filter, *args, timeout=None):
1791
+ '''
1792
+ List gets a list of RemoteIdentityGroups matching a given set of criteria.
1793
+ '''
1794
+ return self.remote_identity_groups.list(filter, *args, timeout=timeout)
1795
+
1796
+
1797
+ class RemoteIdentityGroupsHistory:
1798
+ '''
1799
+ RemoteIdentityGroupsHistory records all changes to the state of a RemoteIdentityGroup.
1800
+ See `strongdm.models.RemoteIdentityGroupHistory`.
1801
+ '''
1802
+ def __init__(self, channel, client):
1803
+ self.parent = client
1804
+ self.stub = RemoteIdentityGroupsHistoryStub(channel)
1805
+
1806
+ def list(self, filter, *args, timeout=None):
1807
+ '''
1808
+ List gets a list of RemoteIdentityGroupHistory records matching a given set of criteria.
1809
+ '''
1810
+ req = RemoteIdentityGroupHistoryListRequest()
1811
+ req.meta.CopyFrom(ListRequestMetadata())
1812
+ page_size_option = self.parent._test_options.get('PageSize')
1813
+ if isinstance(page_size_option, int):
1814
+ req.meta.limit = page_size_option
1815
+ if self.parent.snapshot_datetime is not None:
1816
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1817
+
1818
+ req.filter = plumbing.quote_filter_args(filter, *args)
1819
+
1820
+ def generator(svc, req):
1821
+ tries = 0
1822
+ while True:
1823
+ try:
1824
+ plumbing_response = svc.stub.List(
1825
+ req,
1826
+ metadata=svc.parent.get_metadata(
1827
+ 'RemoteIdentityGroupsHistory.List', req),
1828
+ timeout=timeout)
1829
+ except Exception as e:
1830
+ if self.parent.shouldRetry(tries, e):
1831
+ tries += 1
1832
+ self.parent.jitterSleep(tries)
1833
+ continue
1834
+ raise plumbing.convert_error_to_porcelain(e) from e
1835
+ tries = 0
1836
+ for plumbing_item in plumbing_response.history:
1837
+ yield plumbing.convert_remote_identity_group_history_to_porcelain(
1838
+ plumbing_item)
1839
+ if plumbing_response.meta.next_cursor == '':
1840
+ break
1841
+ req.meta.cursor = plumbing_response.meta.next_cursor
1842
+
1843
+ return generator(self, req)
1844
+
1845
+
1846
+ class Replays:
1847
+ '''
1848
+ A Replay captures the data transferred over a long-running SSH, RDP, or Kubernetes interactive session
1849
+ (otherwise referred to as a query). The Replays service is read-only.
1850
+ See `strongdm.models.ReplayChunk`.
1851
+ '''
1852
+ def __init__(self, channel, client):
1853
+ self.parent = client
1854
+ self.stub = ReplaysStub(channel)
1855
+
1856
+ def list(self, filter, *args, timeout=None):
1857
+ '''
1858
+ List gets a list of ReplayChunks for the Query ID specified by the filter criteria.
1014
1859
  '''
1015
- req = RemoteIdentityGroupListRequest()
1860
+ req = ReplayListRequest()
1016
1861
  req.meta.CopyFrom(ListRequestMetadata())
1017
1862
  page_size_option = self.parent._test_options.get('PageSize')
1018
1863
  if isinstance(page_size_option, int):
1019
1864
  req.meta.limit = page_size_option
1865
+ if self.parent.snapshot_datetime is not None:
1866
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1020
1867
 
1021
1868
  req.filter = plumbing.quote_filter_args(filter, *args)
1022
1869
 
@@ -1026,8 +1873,7 @@ class RemoteIdentityGroups:
1026
1873
  try:
1027
1874
  plumbing_response = svc.stub.List(
1028
1875
  req,
1029
- metadata=svc.parent.get_metadata(
1030
- 'RemoteIdentityGroups.List', req),
1876
+ metadata=svc.parent.get_metadata('Replays.List', req),
1031
1877
  timeout=timeout)
1032
1878
  except Exception as e:
1033
1879
  if self.parent.shouldRetry(tries, e):
@@ -1036,8 +1882,8 @@ class RemoteIdentityGroups:
1036
1882
  continue
1037
1883
  raise plumbing.convert_error_to_porcelain(e) from e
1038
1884
  tries = 0
1039
- for plumbing_item in plumbing_response.remote_identity_groups:
1040
- yield plumbing.convert_remote_identity_group_to_porcelain(
1885
+ for plumbing_item in plumbing_response.chunks:
1886
+ yield plumbing.convert_replay_chunk_to_porcelain(
1041
1887
  plumbing_item)
1042
1888
  if plumbing_response.meta.next_cursor == '':
1043
1889
  break
@@ -1141,6 +1987,8 @@ class Resources:
1141
1987
  page_size_option = self.parent._test_options.get('PageSize')
1142
1988
  if isinstance(page_size_option, int):
1143
1989
  req.meta.limit = page_size_option
1990
+ if self.parent.snapshot_datetime is not None:
1991
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1144
1992
 
1145
1993
  req.filter = plumbing.quote_filter_args(filter, *args)
1146
1994
 
@@ -1207,6 +2055,9 @@ class Resources:
1207
2055
  Get reads one Resource by ID.
1208
2056
  '''
1209
2057
  req = ResourceGetRequest()
2058
+ if self.parent.snapshot_datetime is not None:
2059
+ req.meta.CopyFrom(GetRequestMetadata())
2060
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1210
2061
 
1211
2062
  req.id = (id)
1212
2063
  tries = 0
@@ -1307,6 +2158,8 @@ class Resources:
1307
2158
  page_size_option = self.parent._test_options.get('PageSize')
1308
2159
  if isinstance(page_size_option, int):
1309
2160
  req.meta.limit = page_size_option
2161
+ if self.parent.snapshot_datetime is not None:
2162
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1310
2163
 
1311
2164
  req.filter = plumbing.quote_filter_args(filter, *args)
1312
2165
 
@@ -1335,6 +2188,190 @@ class Resources:
1335
2188
  return generator(self, req)
1336
2189
 
1337
2190
 
2191
+ class SnapshotResources:
2192
+ '''
2193
+ SnapshotResources exposes the read only methods of the Resources
2194
+ service for historical queries.
2195
+ '''
2196
+ def __init__(self, resources):
2197
+ self.resources = resources
2198
+
2199
+ def get(self, id, timeout=None):
2200
+ '''
2201
+ Get reads one Resource by ID.
2202
+ '''
2203
+ return self.resources.get(id, timeout=timeout)
2204
+
2205
+ def list(self, filter, *args, timeout=None):
2206
+ '''
2207
+ List gets a list of Resources matching a given set of criteria.
2208
+ '''
2209
+ return self.resources.list(filter, *args, timeout=timeout)
2210
+
2211
+
2212
+ class ResourcesHistory:
2213
+ '''
2214
+ ResourcesHistory records all changes to the state of a Resource.
2215
+ See `strongdm.models.ResourceHistory`.
2216
+ '''
2217
+ def __init__(self, channel, client):
2218
+ self.parent = client
2219
+ self.stub = ResourcesHistoryStub(channel)
2220
+
2221
+ def list(self, filter, *args, timeout=None):
2222
+ '''
2223
+ List gets a list of ResourceHistory records matching a given set of criteria.
2224
+ '''
2225
+ req = ResourceHistoryListRequest()
2226
+ req.meta.CopyFrom(ListRequestMetadata())
2227
+ page_size_option = self.parent._test_options.get('PageSize')
2228
+ if isinstance(page_size_option, int):
2229
+ req.meta.limit = page_size_option
2230
+ if self.parent.snapshot_datetime is not None:
2231
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
2232
+
2233
+ req.filter = plumbing.quote_filter_args(filter, *args)
2234
+
2235
+ def generator(svc, req):
2236
+ tries = 0
2237
+ while True:
2238
+ try:
2239
+ plumbing_response = svc.stub.List(
2240
+ req,
2241
+ metadata=svc.parent.get_metadata(
2242
+ 'ResourcesHistory.List', req),
2243
+ timeout=timeout)
2244
+ except Exception as e:
2245
+ if self.parent.shouldRetry(tries, e):
2246
+ tries += 1
2247
+ self.parent.jitterSleep(tries)
2248
+ continue
2249
+ raise plumbing.convert_error_to_porcelain(e) from e
2250
+ tries = 0
2251
+ for plumbing_item in plumbing_response.history:
2252
+ yield plumbing.convert_resource_history_to_porcelain(
2253
+ plumbing_item)
2254
+ if plumbing_response.meta.next_cursor == '':
2255
+ break
2256
+ req.meta.cursor = plumbing_response.meta.next_cursor
2257
+
2258
+ return generator(self, req)
2259
+
2260
+
2261
+ class RoleResources:
2262
+ '''
2263
+ RoleResources enumerates the resources to which roles have access.
2264
+ The RoleResources service is read-only.
2265
+ See `strongdm.models.RoleResource`.
2266
+ '''
2267
+ def __init__(self, channel, client):
2268
+ self.parent = client
2269
+ self.stub = RoleResourcesStub(channel)
2270
+
2271
+ def list(self, filter, *args, timeout=None):
2272
+ '''
2273
+ List gets a list of RoleResource records matching a given set of criteria.
2274
+ '''
2275
+ req = RoleResourceListRequest()
2276
+ req.meta.CopyFrom(ListRequestMetadata())
2277
+ page_size_option = self.parent._test_options.get('PageSize')
2278
+ if isinstance(page_size_option, int):
2279
+ req.meta.limit = page_size_option
2280
+ if self.parent.snapshot_datetime is not None:
2281
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
2282
+
2283
+ req.filter = plumbing.quote_filter_args(filter, *args)
2284
+
2285
+ def generator(svc, req):
2286
+ tries = 0
2287
+ while True:
2288
+ try:
2289
+ plumbing_response = svc.stub.List(
2290
+ req,
2291
+ metadata=svc.parent.get_metadata(
2292
+ 'RoleResources.List', req),
2293
+ timeout=timeout)
2294
+ except Exception as e:
2295
+ if self.parent.shouldRetry(tries, e):
2296
+ tries += 1
2297
+ self.parent.jitterSleep(tries)
2298
+ continue
2299
+ raise plumbing.convert_error_to_porcelain(e) from e
2300
+ tries = 0
2301
+ for plumbing_item in plumbing_response.role_resources:
2302
+ yield plumbing.convert_role_resource_to_porcelain(
2303
+ plumbing_item)
2304
+ if plumbing_response.meta.next_cursor == '':
2305
+ break
2306
+ req.meta.cursor = plumbing_response.meta.next_cursor
2307
+
2308
+ return generator(self, req)
2309
+
2310
+
2311
+ class SnapshotRoleResources:
2312
+ '''
2313
+ SnapshotRoleResources exposes the read only methods of the RoleResources
2314
+ service for historical queries.
2315
+ '''
2316
+ def __init__(self, role_resources):
2317
+ self.role_resources = role_resources
2318
+
2319
+ def list(self, filter, *args, timeout=None):
2320
+ '''
2321
+ List gets a list of RoleResource records matching a given set of criteria.
2322
+ '''
2323
+ return self.role_resources.list(filter, *args, timeout=timeout)
2324
+
2325
+
2326
+ class RoleResourcesHistory:
2327
+ '''
2328
+ RoleResourcesHistory records all changes to the state of a RoleResource.
2329
+ See `strongdm.models.RoleResourceHistory`.
2330
+ '''
2331
+ def __init__(self, channel, client):
2332
+ self.parent = client
2333
+ self.stub = RoleResourcesHistoryStub(channel)
2334
+
2335
+ def list(self, filter, *args, timeout=None):
2336
+ '''
2337
+ List gets a list of RoleResourceHistory records matching a given set of criteria.
2338
+ '''
2339
+ req = RoleResourceHistoryListRequest()
2340
+ req.meta.CopyFrom(ListRequestMetadata())
2341
+ page_size_option = self.parent._test_options.get('PageSize')
2342
+ if isinstance(page_size_option, int):
2343
+ req.meta.limit = page_size_option
2344
+ if self.parent.snapshot_datetime is not None:
2345
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
2346
+
2347
+ req.filter = plumbing.quote_filter_args(filter, *args)
2348
+
2349
+ def generator(svc, req):
2350
+ tries = 0
2351
+ while True:
2352
+ try:
2353
+ plumbing_response = svc.stub.List(
2354
+ req,
2355
+ metadata=svc.parent.get_metadata(
2356
+ 'RoleResourcesHistory.List', req),
2357
+ timeout=timeout)
2358
+ except Exception as e:
2359
+ if self.parent.shouldRetry(tries, e):
2360
+ tries += 1
2361
+ self.parent.jitterSleep(tries)
2362
+ continue
2363
+ raise plumbing.convert_error_to_porcelain(e) from e
2364
+ tries = 0
2365
+ for plumbing_item in plumbing_response.history:
2366
+ yield plumbing.convert_role_resource_history_to_porcelain(
2367
+ plumbing_item)
2368
+ if plumbing_response.meta.next_cursor == '':
2369
+ break
2370
+ req.meta.cursor = plumbing_response.meta.next_cursor
2371
+
2372
+ return generator(self, req)
2373
+
2374
+
1338
2375
  class Roles:
1339
2376
  '''
1340
2377
  A Role has a list of access rules which determine which Resources the members
@@ -1383,6 +2420,9 @@ class Roles:
1383
2420
  Get reads one Role by ID.
1384
2421
  '''
1385
2422
  req = RoleGetRequest()
2423
+ if self.parent.snapshot_datetime is not None:
2424
+ req.meta.CopyFrom(GetRequestMetadata())
2425
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1386
2426
 
1387
2427
  req.id = (id)
1388
2428
  tries = 0
@@ -1480,6 +2520,8 @@ class Roles:
1480
2520
  page_size_option = self.parent._test_options.get('PageSize')
1481
2521
  if isinstance(page_size_option, int):
1482
2522
  req.meta.limit = page_size_option
2523
+ if self.parent.snapshot_datetime is not None:
2524
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1483
2525
 
1484
2526
  req.filter = plumbing.quote_filter_args(filter, *args)
1485
2527
 
@@ -1507,6 +2549,76 @@ class Roles:
1507
2549
  return generator(self, req)
1508
2550
 
1509
2551
 
2552
+ class SnapshotRoles:
2553
+ '''
2554
+ SnapshotRoles exposes the read only methods of the Roles
2555
+ service for historical queries.
2556
+ '''
2557
+ def __init__(self, roles):
2558
+ self.roles = roles
2559
+
2560
+ def get(self, id, timeout=None):
2561
+ '''
2562
+ Get reads one Role by ID.
2563
+ '''
2564
+ return self.roles.get(id, timeout=timeout)
2565
+
2566
+ def list(self, filter, *args, timeout=None):
2567
+ '''
2568
+ List gets a list of Roles matching a given set of criteria.
2569
+ '''
2570
+ return self.roles.list(filter, *args, timeout=timeout)
2571
+
2572
+
2573
+ class RolesHistory:
2574
+ '''
2575
+ RolesHistory records all changes to the state of a Role.
2576
+ See `strongdm.models.RoleHistory`.
2577
+ '''
2578
+ def __init__(self, channel, client):
2579
+ self.parent = client
2580
+ self.stub = RolesHistoryStub(channel)
2581
+
2582
+ def list(self, filter, *args, timeout=None):
2583
+ '''
2584
+ List gets a list of RoleHistory records matching a given set of criteria.
2585
+ '''
2586
+ req = RoleHistoryListRequest()
2587
+ req.meta.CopyFrom(ListRequestMetadata())
2588
+ page_size_option = self.parent._test_options.get('PageSize')
2589
+ if isinstance(page_size_option, int):
2590
+ req.meta.limit = page_size_option
2591
+ if self.parent.snapshot_datetime is not None:
2592
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
2593
+
2594
+ req.filter = plumbing.quote_filter_args(filter, *args)
2595
+
2596
+ def generator(svc, req):
2597
+ tries = 0
2598
+ while True:
2599
+ try:
2600
+ plumbing_response = svc.stub.List(
2601
+ req,
2602
+ metadata=svc.parent.get_metadata(
2603
+ 'RolesHistory.List', req),
2604
+ timeout=timeout)
2605
+ except Exception as e:
2606
+ if self.parent.shouldRetry(tries, e):
2607
+ tries += 1
2608
+ self.parent.jitterSleep(tries)
2609
+ continue
2610
+ raise plumbing.convert_error_to_porcelain(e) from e
2611
+ tries = 0
2612
+ for plumbing_item in plumbing_response.history:
2613
+ yield plumbing.convert_role_history_to_porcelain(
2614
+ plumbing_item)
2615
+ if plumbing_response.meta.next_cursor == '':
2616
+ break
2617
+ req.meta.cursor = plumbing_response.meta.next_cursor
2618
+
2619
+ return generator(self, req)
2620
+
2621
+
1510
2622
  class SecretStores:
1511
2623
  '''
1512
2624
  SecretStores are servers where resource secrets (passwords, keys) are stored.
@@ -1563,6 +2675,9 @@ class SecretStores:
1563
2675
  Get reads one SecretStore by ID.
1564
2676
  '''
1565
2677
  req = SecretStoreGetRequest()
2678
+ if self.parent.snapshot_datetime is not None:
2679
+ req.meta.CopyFrom(GetRequestMetadata())
2680
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1566
2681
 
1567
2682
  req.id = (id)
1568
2683
  tries = 0
@@ -1665,6 +2780,8 @@ class SecretStores:
1665
2780
  page_size_option = self.parent._test_options.get('PageSize')
1666
2781
  if isinstance(page_size_option, int):
1667
2782
  req.meta.limit = page_size_option
2783
+ if self.parent.snapshot_datetime is not None:
2784
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
1668
2785
 
1669
2786
  req.filter = plumbing.quote_filter_args(filter, *args)
1670
2787
 
@@ -1692,3 +2809,73 @@ class SecretStores:
1692
2809
  req.meta.cursor = plumbing_response.meta.next_cursor
1693
2810
 
1694
2811
  return generator(self, req)
2812
+
2813
+
2814
+ class SnapshotSecretStores:
2815
+ '''
2816
+ SnapshotSecretStores exposes the read only methods of the SecretStores
2817
+ service for historical queries.
2818
+ '''
2819
+ def __init__(self, secret_stores):
2820
+ self.secret_stores = secret_stores
2821
+
2822
+ def get(self, id, timeout=None):
2823
+ '''
2824
+ Get reads one SecretStore by ID.
2825
+ '''
2826
+ return self.secret_stores.get(id, timeout=timeout)
2827
+
2828
+ def list(self, filter, *args, timeout=None):
2829
+ '''
2830
+ List gets a list of SecretStores matching a given set of criteria.
2831
+ '''
2832
+ return self.secret_stores.list(filter, *args, timeout=timeout)
2833
+
2834
+
2835
+ class SecretStoresHistory:
2836
+ '''
2837
+ SecretStoresHistory records all changes to the state of a SecretStore.
2838
+ See `strongdm.models.SecretStoreHistory`.
2839
+ '''
2840
+ def __init__(self, channel, client):
2841
+ self.parent = client
2842
+ self.stub = SecretStoresHistoryStub(channel)
2843
+
2844
+ def list(self, filter, *args, timeout=None):
2845
+ '''
2846
+ List gets a list of SecretStoreHistory records matching a given set of criteria.
2847
+ '''
2848
+ req = SecretStoreHistoryListRequest()
2849
+ req.meta.CopyFrom(ListRequestMetadata())
2850
+ page_size_option = self.parent._test_options.get('PageSize')
2851
+ if isinstance(page_size_option, int):
2852
+ req.meta.limit = page_size_option
2853
+ if self.parent.snapshot_datetime is not None:
2854
+ req.meta.snapshot_at.FromDatetime(self.parent.snapshot_datetime)
2855
+
2856
+ req.filter = plumbing.quote_filter_args(filter, *args)
2857
+
2858
+ def generator(svc, req):
2859
+ tries = 0
2860
+ while True:
2861
+ try:
2862
+ plumbing_response = svc.stub.List(
2863
+ req,
2864
+ metadata=svc.parent.get_metadata(
2865
+ 'SecretStoresHistory.List', req),
2866
+ timeout=timeout)
2867
+ except Exception as e:
2868
+ if self.parent.shouldRetry(tries, e):
2869
+ tries += 1
2870
+ self.parent.jitterSleep(tries)
2871
+ continue
2872
+ raise plumbing.convert_error_to_porcelain(e) from e
2873
+ tries = 0
2874
+ for plumbing_item in plumbing_response.history:
2875
+ yield plumbing.convert_secret_store_history_to_porcelain(
2876
+ plumbing_item)
2877
+ if plumbing_response.meta.next_cursor == '':
2878
+ break
2879
+ req.meta.cursor = plumbing_response.meta.next_cursor
2880
+
2881
+ return generator(self, req)