Skip to content

Commit 472da8b

Browse files
committed
15.28.0
1 parent bf41fb9 commit 472da8b

File tree

10 files changed

+834
-285
lines changed

10 files changed

+834
-285
lines changed

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
setup(
2424
name='strongdm',
2525
packages=['strongdm'],
26-
version='15.26.0',
26+
version='15.28.0',
2727
license='apache-2.0',
2828
description='strongDM SDK for the Python programming language.',
2929
long_description=long_description,
@@ -32,7 +32,7 @@
3232
author_email='[email protected]',
3333
url='https://github.com/strongdm/strongdm-sdk-python',
3434
download_url=
35-
'https://github.com/strongdm/strongdm-sdk-python/archive/v15.26.0.tar.gz',
35+
'https://github.com/strongdm/strongdm-sdk-python/archive/v15.28.0.tar.gz',
3636
keywords=[
3737
'strongDM', 'sdm', 'api', 'automation', 'security', 'audit',
3838
'database', 'server', 'ssh', 'rdp'

strongdm.egg-info/PKG-INFO

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Metadata-Version: 2.1
22
Name: strongdm
3-
Version: 15.26.0
3+
Version: 15.28.0
44
Summary: strongDM SDK for the Python programming language.
55
Home-page: https://github.com/strongdm/strongdm-sdk-python
66
Author: strongDM Team
77
Author-email: [email protected]
88
License: apache-2.0
9-
Download-URL: https://github.com/strongdm/strongdm-sdk-python/archive/v15.26.0.tar.gz
9+
Download-URL: https://github.com/strongdm/strongdm-sdk-python/archive/v15.28.0.tar.gz
1010
Keywords: strongDM,sdm,api,automation,security,audit,database,server,ssh,rdp
1111
Platform: UNKNOWN
1212
Classifier: Development Status :: 4 - Beta

strongdm/client.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
DEFAULT_RETRY_FACTOR = 1.6
3535
DEFAULT_RETRY_JITTER = 0.2
3636
API_VERSION = '2025-04-14'
37-
USER_AGENT = 'strongdm-sdk-python/15.26.0'
37+
USER_AGENT = 'strongdm-sdk-python/15.28.0'
3838

3939

4040
class Client:
@@ -294,9 +294,11 @@ def __init__(self,
294294
'''
295295
self.nodes = svc.Nodes(channel, self)
296296
'''
297-
Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
298-
- **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
299-
- **Relays** are used to extend the strongDM network into segmented subnets. They provide access to databases and servers but do not listen for incoming connections.
297+
Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
298+
There are three types of nodes:
299+
1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
300+
2. **Gateway:** a relay that also listens for connections from StrongDM clients
301+
3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
300302
301303
See `strongdm.svc.Nodes`.
302304
'''
@@ -735,9 +737,11 @@ def __init__(self, client):
735737
'''
736738
self.nodes = svc.SnapshotNodes(client.nodes)
737739
'''
738-
Nodes make up the strongDM network, and allow your users to connect securely to your resources. There are two types of nodes:
739-
- **Gateways** are the entry points into network. They listen for connection from the strongDM client, and provide access to databases and servers.
740-
- **Relays** are used to extend the strongDM network into segmented subnets. They provide access to databases and servers but do not listen for incoming connections.
740+
Nodes make up the StrongDM network, and allow your users to connect securely to your resources.
741+
There are three types of nodes:
742+
1. **Relay:** creates connectivity to your datasources, while maintaining the egress-only nature of your firewall
743+
2. **Gateway:** a relay that also listens for connections from StrongDM clients
744+
3. **Proxy Cluster:** a cluster of workers that together mediate access from clients to resources
741745
742746
See `strongdm.svc.SnapshotNodes`.
743747
'''

strongdm/drivers_pb2.py

Lines changed: 274 additions & 222 deletions
Large diffs are not rendered by default.

strongdm/models.py

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12769,6 +12769,185 @@ def from_dict(cls, d):
1276912769
)
1277012770

1277112771

12772+
class ElasticacheRedisIAM:
12773+
'''
12774+
ElasticacheRedisIAM is currently unstable, and its API may change, or it may be removed,
12775+
without a major version bump.
12776+
'''
12777+
__slots__ = [
12778+
'bind_interface',
12779+
'egress_filter',
12780+
'healthy',
12781+
'hostname',
12782+
'id',
12783+
'name',
12784+
'port',
12785+
'port_override',
12786+
'proxy_cluster_id',
12787+
'region',
12788+
'role_assumption_arn',
12789+
'role_external_id',
12790+
'secret_store_id',
12791+
'subdomain',
12792+
'tags',
12793+
'tls_required',
12794+
'username',
12795+
]
12796+
12797+
def __init__(
12798+
self,
12799+
bind_interface=None,
12800+
egress_filter=None,
12801+
healthy=None,
12802+
hostname=None,
12803+
id=None,
12804+
name=None,
12805+
port=None,
12806+
port_override=None,
12807+
proxy_cluster_id=None,
12808+
region=None,
12809+
role_assumption_arn=None,
12810+
role_external_id=None,
12811+
secret_store_id=None,
12812+
subdomain=None,
12813+
tags=None,
12814+
tls_required=None,
12815+
username=None,
12816+
):
12817+
self.bind_interface = bind_interface if bind_interface is not None else ''
12818+
'''
12819+
The bind interface is the IP address to which the port override of a resource is bound (for example, 127.0.0.1). It is automatically generated if not provided and may also be set to one of the ResourceIPAllocationMode constants to select between VNM, loopback, or default allocation.
12820+
'''
12821+
self.egress_filter = egress_filter if egress_filter is not None else ''
12822+
'''
12823+
A filter applied to the routing logic to pin datasource to nodes.
12824+
'''
12825+
self.healthy = healthy if healthy is not None else False
12826+
'''
12827+
True if the datasource is reachable and the credentials are valid.
12828+
'''
12829+
self.hostname = hostname if hostname is not None else ''
12830+
'''
12831+
The host to dial to initiate a connection from the egress node to this resource.
12832+
'''
12833+
self.id = id if id is not None else ''
12834+
'''
12835+
Unique identifier of the Resource.
12836+
'''
12837+
self.name = name if name is not None else ''
12838+
'''
12839+
Unique human-readable name of the Resource.
12840+
'''
12841+
self.port = port if port is not None else 0
12842+
'''
12843+
The port to dial to initiate a connection from the egress node to this resource.
12844+
'''
12845+
self.port_override = port_override if port_override is not None else 0
12846+
'''
12847+
The local port used by clients to connect to this resource. It is automatically generated if not provided on create and may be re-generated on update by specifying a value of -1.
12848+
'''
12849+
self.proxy_cluster_id = proxy_cluster_id if proxy_cluster_id is not None else ''
12850+
'''
12851+
ID of the proxy cluster for this resource, if any.
12852+
'''
12853+
self.region = region if region is not None else ''
12854+
'''
12855+
AWS region is needed in addition to hostname to generate the IAM signature
12856+
'''
12857+
self.role_assumption_arn = role_assumption_arn if role_assumption_arn is not None else ''
12858+
'''
12859+
If provided, the gateway/relay will try to assume this role instead of the underlying compute's role.
12860+
'''
12861+
self.role_external_id = role_external_id if role_external_id is not None else ''
12862+
'''
12863+
The external ID to associate with assume role requests. Does nothing if a role ARN is not provided.
12864+
'''
12865+
self.secret_store_id = secret_store_id if secret_store_id is not None else ''
12866+
'''
12867+
ID of the secret store containing credentials for this resource, if any.
12868+
'''
12869+
self.subdomain = subdomain if subdomain is not None else ''
12870+
'''
12871+
DNS subdomain through which this resource may be accessed on clients. (e.g. "app-prod1" allows the resource to be accessed at "app-prod1.your-org-name.sdm-proxy-domain"). Only applicable to HTTP-based resources or resources using virtual networking mode.
12872+
'''
12873+
self.tags = tags if tags is not None else _porcelain_zero_value_tags()
12874+
'''
12875+
Tags is a map of key, value pairs.
12876+
'''
12877+
self.tls_required = tls_required if tls_required is not None else False
12878+
'''
12879+
If set, TLS must be used to connect to this resource.
12880+
'''
12881+
self.username = username if username is not None else ''
12882+
'''
12883+
The username to authenticate with.
12884+
'''
12885+
12886+
def __repr__(self):
12887+
return '<sdm.ElasticacheRedisIAM ' + \
12888+
'bind_interface: ' + repr(self.bind_interface) + ' ' +\
12889+
'egress_filter: ' + repr(self.egress_filter) + ' ' +\
12890+
'healthy: ' + repr(self.healthy) + ' ' +\
12891+
'hostname: ' + repr(self.hostname) + ' ' +\
12892+
'id: ' + repr(self.id) + ' ' +\
12893+
'name: ' + repr(self.name) + ' ' +\
12894+
'port: ' + repr(self.port) + ' ' +\
12895+
'port_override: ' + repr(self.port_override) + ' ' +\
12896+
'proxy_cluster_id: ' + repr(self.proxy_cluster_id) + ' ' +\
12897+
'region: ' + repr(self.region) + ' ' +\
12898+
'role_assumption_arn: ' + repr(self.role_assumption_arn) + ' ' +\
12899+
'role_external_id: ' + repr(self.role_external_id) + ' ' +\
12900+
'secret_store_id: ' + repr(self.secret_store_id) + ' ' +\
12901+
'subdomain: ' + repr(self.subdomain) + ' ' +\
12902+
'tags: ' + repr(self.tags) + ' ' +\
12903+
'tls_required: ' + repr(self.tls_required) + ' ' +\
12904+
'username: ' + repr(self.username) + ' ' +\
12905+
'>'
12906+
12907+
def to_dict(self):
12908+
return {
12909+
'bind_interface': self.bind_interface,
12910+
'egress_filter': self.egress_filter,
12911+
'healthy': self.healthy,
12912+
'hostname': self.hostname,
12913+
'id': self.id,
12914+
'name': self.name,
12915+
'port': self.port,
12916+
'port_override': self.port_override,
12917+
'proxy_cluster_id': self.proxy_cluster_id,
12918+
'region': self.region,
12919+
'role_assumption_arn': self.role_assumption_arn,
12920+
'role_external_id': self.role_external_id,
12921+
'secret_store_id': self.secret_store_id,
12922+
'subdomain': self.subdomain,
12923+
'tags': self.tags,
12924+
'tls_required': self.tls_required,
12925+
'username': self.username,
12926+
}
12927+
12928+
@classmethod
12929+
def from_dict(cls, d):
12930+
return cls(
12931+
bind_interface=d.get('bind_interface'),
12932+
egress_filter=d.get('egress_filter'),
12933+
healthy=d.get('healthy'),
12934+
hostname=d.get('hostname'),
12935+
id=d.get('id'),
12936+
name=d.get('name'),
12937+
port=d.get('port'),
12938+
port_override=d.get('port_override'),
12939+
proxy_cluster_id=d.get('proxy_cluster_id'),
12940+
region=d.get('region'),
12941+
role_assumption_arn=d.get('role_assumption_arn'),
12942+
role_external_id=d.get('role_external_id'),
12943+
secret_store_id=d.get('secret_store_id'),
12944+
subdomain=d.get('subdomain'),
12945+
tags=d.get('tags'),
12946+
tls_required=d.get('tls_required'),
12947+
username=d.get('username'),
12948+
)
12949+
12950+
1277212951
class EntraID:
1277312952
__slots__ = [
1277412953
'bind_interface',
@@ -22055,6 +22234,67 @@ def from_dict(cls, d):
2205522234
)
2205622235

2205722236

22237+
class NodeTCPProbeResponse:
22238+
'''
22239+
NodeTCPProbeResponse reports the result of a TCP probe.
22240+
'''
22241+
__slots__ = [
22242+
'error',
22243+
'meta',
22244+
'rate_limit',
22245+
'succeeded',
22246+
]
22247+
22248+
def __init__(
22249+
self,
22250+
error=None,
22251+
meta=None,
22252+
rate_limit=None,
22253+
succeeded=None,
22254+
):
22255+
self.error = error if error is not None else ''
22256+
'''
22257+
The connection error reported by the node, or the empty string if the probe succeeded.
22258+
'''
22259+
self.meta = meta if meta is not None else None
22260+
'''
22261+
Reserved for future use.
22262+
'''
22263+
self.rate_limit = rate_limit if rate_limit is not None else None
22264+
'''
22265+
Rate limit information.
22266+
'''
22267+
self.succeeded = succeeded if succeeded is not None else False
22268+
'''
22269+
True if the node was able to connect to the target address.
22270+
'''
22271+
22272+
def __repr__(self):
22273+
return '<sdm.NodeTCPProbeResponse ' + \
22274+
'error: ' + repr(self.error) + ' ' +\
22275+
'meta: ' + repr(self.meta) + ' ' +\
22276+
'rate_limit: ' + repr(self.rate_limit) + ' ' +\
22277+
'succeeded: ' + repr(self.succeeded) + ' ' +\
22278+
'>'
22279+
22280+
def to_dict(self):
22281+
return {
22282+
'error': self.error,
22283+
'meta': self.meta,
22284+
'rate_limit': self.rate_limit,
22285+
'succeeded': self.succeeded,
22286+
}
22287+
22288+
@classmethod
22289+
def from_dict(cls, d):
22290+
return cls(
22291+
error=d.get('error'),
22292+
meta=d.get('meta'),
22293+
rate_limit=d.get('rate_limit'),
22294+
succeeded=d.get('succeeded'),
22295+
)
22296+
22297+
2205822298
class NodeUpdateResponse:
2205922299
'''
2206022300
NodeUpdateResponse returns the fields of a Node after it has been updated by
@@ -25212,6 +25452,8 @@ class RDP:
2521225452
'healthy',
2521325453
'hostname',
2521425454
'id',
25455+
'identity_alias_healthcheck_username',
25456+
'identity_set_id',
2521525457
'lock_required',
2521625458
'name',
2521725459
'password',
@@ -25232,6 +25474,8 @@ def __init__(
2523225474
healthy=None,
2523325475
hostname=None,
2523425476
id=None,
25477+
identity_alias_healthcheck_username=None,
25478+
identity_set_id=None,
2523525479
lock_required=None,
2523625480
name=None,
2523725481
password=None,
@@ -25267,6 +25511,14 @@ def __init__(
2526725511
'''
2526825512
Unique identifier of the Resource.
2526925513
'''
25514+
self.identity_alias_healthcheck_username = identity_alias_healthcheck_username if identity_alias_healthcheck_username is not None else ''
25515+
'''
25516+
The username to use for healthchecks, when clients otherwise connect with their own identity alias username.
25517+
'''
25518+
self.identity_set_id = identity_set_id if identity_set_id is not None else ''
25519+
'''
25520+
if provided use identity_set to map username to secret store path
25521+
'''
2527025522
self.lock_required = lock_required if lock_required is not None else False
2527125523
'''
2527225524
When set, require a resource lock to access the resource to ensure it can only be used by one user at a time.
@@ -25316,6 +25568,8 @@ def __repr__(self):
2531625568
'healthy: ' + repr(self.healthy) + ' ' +\
2531725569
'hostname: ' + repr(self.hostname) + ' ' +\
2531825570
'id: ' + repr(self.id) + ' ' +\
25571+
'identity_alias_healthcheck_username: ' + repr(self.identity_alias_healthcheck_username) + ' ' +\
25572+
'identity_set_id: ' + repr(self.identity_set_id) + ' ' +\
2531925573
'lock_required: ' + repr(self.lock_required) + ' ' +\
2532025574
'name: ' + repr(self.name) + ' ' +\
2532125575
'password: ' + repr(self.password) + ' ' +\
@@ -25336,6 +25590,9 @@ def to_dict(self):
2533625590
'healthy': self.healthy,
2533725591
'hostname': self.hostname,
2533825592
'id': self.id,
25593+
'identity_alias_healthcheck_username':
25594+
self.identity_alias_healthcheck_username,
25595+
'identity_set_id': self.identity_set_id,
2533925596
'lock_required': self.lock_required,
2534025597
'name': self.name,
2534125598
'password': self.password,
@@ -25357,6 +25614,9 @@ def from_dict(cls, d):
2535725614
healthy=d.get('healthy'),
2535825615
hostname=d.get('hostname'),
2535925616
id=d.get('id'),
25617+
identity_alias_healthcheck_username=d.get(
25618+
'identity_alias_healthcheck_username'),
25619+
identity_set_id=d.get('identity_set_id'),
2536025620
lock_required=d.get('lock_required'),
2536125621
name=d.get('name'),
2536225622
password=d.get('password'),

0 commit comments

Comments
 (0)