cribl-control-plane 0.0.38__py3-none-any.whl → 0.4.0a6__py3-none-any.whl
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.
Potentially problematic release.
This version of cribl-control-plane might be problematic. Click here for more details.
- cribl_control_plane/_hooks/clientcredentials.py +92 -42
- cribl_control_plane/_version.py +4 -4
- cribl_control_plane/acl.py +5 -3
- cribl_control_plane/auth_sdk.py +6 -3
- cribl_control_plane/basesdk.py +11 -1
- cribl_control_plane/commits.py +7 -5
- cribl_control_plane/destinations.py +6 -4
- cribl_control_plane/destinations_pq.py +2 -2
- cribl_control_plane/errors/__init__.py +23 -8
- cribl_control_plane/errors/apierror.py +2 -0
- cribl_control_plane/errors/criblcontrolplaneerror.py +11 -7
- cribl_control_plane/errors/error.py +4 -2
- cribl_control_plane/errors/healthserverstatus_error.py +41 -0
- cribl_control_plane/errors/no_response_error.py +5 -1
- cribl_control_plane/errors/responsevalidationerror.py +2 -0
- cribl_control_plane/groups_configs.py +8 -3
- cribl_control_plane/groups_sdk.py +64 -38
- cribl_control_plane/health.py +22 -12
- cribl_control_plane/httpclient.py +0 -1
- cribl_control_plane/lakedatasets.py +40 -12
- cribl_control_plane/models/__init__.py +1180 -54
- cribl_control_plane/models/authtoken.py +5 -1
- cribl_control_plane/models/{routecloneconf.py → branchinfo.py} +4 -4
- cribl_control_plane/models/cacheconnection.py +30 -2
- cribl_control_plane/models/cacheconnectionbackfillstatus.py +2 -1
- cribl_control_plane/models/cloudprovider.py +2 -1
- cribl_control_plane/models/configgroup.py +66 -11
- cribl_control_plane/models/configgroupcloud.py +17 -3
- cribl_control_plane/models/createconfiggroupbyproductop.py +27 -9
- cribl_control_plane/models/createinputhectokenbyidop.py +6 -5
- cribl_control_plane/models/createroutesappendbyidop.py +2 -2
- cribl_control_plane/models/createversionpushop.py +5 -5
- cribl_control_plane/models/createversionrevertop.py +2 -2
- cribl_control_plane/models/createversionundoop.py +3 -3
- cribl_control_plane/models/cribllakedataset.py +22 -2
- cribl_control_plane/models/cribllakedatasetupdate.py +95 -0
- cribl_control_plane/models/datasetmetadata.py +18 -2
- cribl_control_plane/models/deleteconfiggroupbyproductandidop.py +18 -2
- cribl_control_plane/models/deleteoutputpqbyidop.py +5 -5
- cribl_control_plane/models/deletepipelinebyidop.py +2 -2
- cribl_control_plane/models/difffiles.py +171 -0
- cribl_control_plane/models/distributedsummary.py +6 -0
- cribl_control_plane/models/getconfiggroupaclbyproductandidop.py +24 -2
- cribl_control_plane/models/getconfiggroupaclteamsbyproductandidop.py +24 -2
- cribl_control_plane/models/getconfiggroupbyproductandidop.py +14 -1
- cribl_control_plane/models/getconfiggroupconfigversionbyproductandidop.py +18 -2
- cribl_control_plane/models/getoutputpqbyidop.py +6 -5
- cribl_control_plane/models/getpipelinebyidop.py +2 -2
- cribl_control_plane/models/getroutesbyidop.py +2 -2
- cribl_control_plane/models/getsummaryop.py +18 -2
- cribl_control_plane/models/getversionbranchop.py +6 -5
- cribl_control_plane/models/getversioncountop.py +6 -5
- cribl_control_plane/models/getversiondiffop.py +6 -5
- cribl_control_plane/models/getversionshowop.py +6 -5
- cribl_control_plane/models/gitcountresult.py +13 -0
- cribl_control_plane/models/gitdiffresult.py +16 -0
- cribl_control_plane/models/gitinfo.py +14 -3
- cribl_control_plane/models/gitshowresult.py +19 -0
- cribl_control_plane/models/groupcreaterequest.py +171 -0
- cribl_control_plane/models/hbcriblinfo.py +39 -3
- cribl_control_plane/models/healthserverstatus.py +55 -0
- cribl_control_plane/models/heartbeatmetadata.py +3 -0
- cribl_control_plane/models/input.py +83 -78
- cribl_control_plane/models/inputappscope.py +126 -30
- cribl_control_plane/models/inputazureblob.py +62 -6
- cribl_control_plane/models/inputcloudflarehec.py +513 -0
- cribl_control_plane/models/inputcollection.py +47 -4
- cribl_control_plane/models/inputconfluentcloud.py +254 -30
- cribl_control_plane/models/inputcribl.py +47 -4
- cribl_control_plane/models/inputcriblhttp.py +121 -30
- cribl_control_plane/models/inputcribllakehttp.py +122 -30
- cribl_control_plane/models/inputcriblmetrics.py +48 -4
- cribl_control_plane/models/inputcribltcp.py +122 -24
- cribl_control_plane/models/inputcrowdstrike.py +92 -10
- cribl_control_plane/models/inputdatadogagent.py +98 -24
- cribl_control_plane/models/inputdatagen.py +47 -4
- cribl_control_plane/models/inputedgeprometheus.py +210 -50
- cribl_control_plane/models/inputelastic.py +167 -36
- cribl_control_plane/models/inputeventhub.py +209 -6
- cribl_control_plane/models/inputexec.py +59 -6
- cribl_control_plane/models/inputfile.py +78 -10
- cribl_control_plane/models/inputfirehose.py +97 -24
- cribl_control_plane/models/inputgooglepubsub.py +67 -6
- cribl_control_plane/models/inputgrafana.py +251 -71
- cribl_control_plane/models/inputhttp.py +97 -24
- cribl_control_plane/models/inputhttpraw.py +97 -24
- cribl_control_plane/models/inputjournalfiles.py +48 -4
- cribl_control_plane/models/inputkafka.py +248 -26
- cribl_control_plane/models/inputkinesis.py +130 -14
- cribl_control_plane/models/inputkubeevents.py +47 -4
- cribl_control_plane/models/inputkubelogs.py +61 -8
- cribl_control_plane/models/inputkubemetrics.py +61 -8
- cribl_control_plane/models/inputloki.py +113 -34
- cribl_control_plane/models/inputmetrics.py +97 -24
- cribl_control_plane/models/inputmodeldriventelemetry.py +107 -26
- cribl_control_plane/models/inputmsk.py +141 -30
- cribl_control_plane/models/inputnetflow.py +47 -4
- cribl_control_plane/models/inputoffice365mgmt.py +112 -14
- cribl_control_plane/models/inputoffice365msgtrace.py +114 -16
- cribl_control_plane/models/inputoffice365service.py +114 -16
- cribl_control_plane/models/inputopentelemetry.py +143 -32
- cribl_control_plane/models/inputprometheus.py +193 -44
- cribl_control_plane/models/inputprometheusrw.py +114 -27
- cribl_control_plane/models/inputrawudp.py +47 -4
- cribl_control_plane/models/inputs3.py +78 -8
- cribl_control_plane/models/inputs3inventory.py +92 -10
- cribl_control_plane/models/inputsecuritylake.py +93 -10
- cribl_control_plane/models/inputsnmp.py +68 -6
- cribl_control_plane/models/inputsplunk.py +130 -28
- cribl_control_plane/models/inputsplunkhec.py +111 -25
- cribl_control_plane/models/inputsplunksearch.py +108 -14
- cribl_control_plane/models/inputsqs.py +99 -16
- cribl_control_plane/models/inputsyslog.py +189 -47
- cribl_control_plane/models/inputsystemmetrics.py +202 -32
- cribl_control_plane/models/inputsystemstate.py +61 -8
- cribl_control_plane/models/inputtcp.py +122 -26
- cribl_control_plane/models/inputtcpjson.py +112 -26
- cribl_control_plane/models/inputwef.py +121 -15
- cribl_control_plane/models/inputwindowsmetrics.py +186 -33
- cribl_control_plane/models/inputwineventlogs.py +93 -11
- cribl_control_plane/models/inputwiz.py +78 -8
- cribl_control_plane/models/inputwizwebhook.py +97 -24
- cribl_control_plane/models/inputzscalerhec.py +111 -25
- cribl_control_plane/models/jobinfo.py +34 -0
- cribl_control_plane/models/jobstatus.py +48 -0
- cribl_control_plane/models/lakedatasetmetrics.py +17 -0
- cribl_control_plane/models/lakehouseconnectiontype.py +2 -1
- cribl_control_plane/models/listconfiggroupbyproductop.py +14 -1
- cribl_control_plane/models/logininfo.py +3 -3
- cribl_control_plane/models/masterworkerentry.py +17 -2
- cribl_control_plane/models/nodeactiveupgradestatus.py +2 -1
- cribl_control_plane/models/nodefailedupgradestatus.py +2 -1
- cribl_control_plane/models/nodeprovidedinfo.py +11 -1
- cribl_control_plane/models/nodeskippedupgradestatus.py +2 -1
- cribl_control_plane/models/nodeupgradestate.py +2 -1
- cribl_control_plane/models/nodeupgradestatus.py +51 -5
- cribl_control_plane/models/outpostnodeinfo.py +16 -0
- cribl_control_plane/models/output.py +104 -90
- cribl_control_plane/models/outputazureblob.py +171 -18
- cribl_control_plane/models/outputazuredataexplorer.py +514 -90
- cribl_control_plane/models/outputazureeventhub.py +315 -31
- cribl_control_plane/models/outputazurelogs.py +145 -26
- cribl_control_plane/models/outputchronicle.py +532 -0
- cribl_control_plane/models/outputclickhouse.py +205 -34
- cribl_control_plane/models/outputcloudflarer2.py +632 -0
- cribl_control_plane/models/outputcloudwatch.py +129 -23
- cribl_control_plane/models/outputconfluentcloud.py +384 -57
- cribl_control_plane/models/outputcriblhttp.py +199 -32
- cribl_control_plane/models/outputcribllake.py +156 -16
- cribl_control_plane/models/outputcribltcp.py +194 -29
- cribl_control_plane/models/outputcrowdstrikenextgensiem.py +172 -28
- cribl_control_plane/models/outputdatabricks.py +501 -0
- cribl_control_plane/models/outputdatadog.py +199 -31
- cribl_control_plane/models/outputdataset.py +181 -29
- cribl_control_plane/models/outputdiskspool.py +17 -2
- cribl_control_plane/models/outputdls3.py +233 -24
- cribl_control_plane/models/outputdynatracehttp.py +208 -34
- cribl_control_plane/models/outputdynatraceotlp.py +210 -36
- cribl_control_plane/models/outputelastic.py +199 -30
- cribl_control_plane/models/outputelasticcloud.py +171 -26
- cribl_control_plane/models/outputexabeam.py +96 -10
- cribl_control_plane/models/outputfilesystem.py +139 -14
- cribl_control_plane/models/outputgooglechronicle.py +216 -35
- cribl_control_plane/models/outputgooglecloudlogging.py +174 -31
- cribl_control_plane/models/outputgooglecloudstorage.py +215 -24
- cribl_control_plane/models/outputgooglepubsub.py +131 -23
- cribl_control_plane/models/outputgrafanacloud.py +376 -74
- cribl_control_plane/models/outputgraphite.py +128 -25
- cribl_control_plane/models/outputhoneycomb.py +145 -26
- cribl_control_plane/models/outputhumiohec.py +162 -28
- cribl_control_plane/models/outputinfluxdb.py +165 -28
- cribl_control_plane/models/outputkafka.py +375 -52
- cribl_control_plane/models/outputkinesis.py +165 -27
- cribl_control_plane/models/outputloki.py +164 -34
- cribl_control_plane/models/outputmicrosoftfabric.py +540 -0
- cribl_control_plane/models/outputminio.py +225 -25
- cribl_control_plane/models/outputmsk.py +267 -54
- cribl_control_plane/models/outputnewrelic.py +171 -29
- cribl_control_plane/models/outputnewrelicevents.py +163 -28
- cribl_control_plane/models/outputopentelemetry.py +240 -40
- cribl_control_plane/models/outputprometheus.py +145 -26
- cribl_control_plane/models/outputring.py +49 -8
- cribl_control_plane/models/outputs3.py +233 -26
- cribl_control_plane/models/outputsecuritylake.py +179 -18
- cribl_control_plane/models/outputsentinel.py +172 -29
- cribl_control_plane/models/outputsentineloneaisiem.py +181 -35
- cribl_control_plane/models/outputservicenow.py +223 -38
- cribl_control_plane/models/outputsignalfx.py +145 -26
- cribl_control_plane/models/outputsns.py +143 -25
- cribl_control_plane/models/outputsplunk.py +206 -36
- cribl_control_plane/models/outputsplunkhec.py +238 -26
- cribl_control_plane/models/outputsplunklb.py +253 -43
- cribl_control_plane/models/outputsqs.py +163 -33
- cribl_control_plane/models/outputstatsd.py +127 -25
- cribl_control_plane/models/outputstatsdext.py +128 -25
- cribl_control_plane/models/outputsumologic.py +146 -25
- cribl_control_plane/models/outputsyslog.py +318 -46
- cribl_control_plane/models/outputtcpjson.py +186 -32
- cribl_control_plane/models/outputwavefront.py +145 -26
- cribl_control_plane/models/outputwebhook.py +211 -33
- cribl_control_plane/models/outputxsiam.py +143 -26
- cribl_control_plane/models/packinfo.py +8 -5
- cribl_control_plane/models/packinstallinfo.py +11 -8
- cribl_control_plane/models/productscore.py +2 -1
- cribl_control_plane/models/rbacresource.py +2 -1
- cribl_control_plane/models/resourcepolicy.py +15 -2
- cribl_control_plane/models/routeconf.py +3 -4
- cribl_control_plane/models/runnablejob.py +27 -0
- cribl_control_plane/models/runnablejobcollection.py +669 -0
- cribl_control_plane/models/runnablejobexecutor.py +368 -0
- cribl_control_plane/models/runnablejobscheduledsearch.py +286 -0
- cribl_control_plane/models/updateconfiggroupbyproductandidop.py +19 -2
- cribl_control_plane/models/updateconfiggroupdeploybyproductandidop.py +19 -2
- cribl_control_plane/models/updatecribllakedatasetbylakeidandidop.py +9 -5
- cribl_control_plane/models/updateinputhectokenbyidandtokenop.py +6 -5
- cribl_control_plane/models/updatepacksop.py +25 -0
- cribl_control_plane/models/updatepipelinebyidop.py +6 -6
- cribl_control_plane/models/updateroutesbyidop.py +2 -2
- cribl_control_plane/models/uploadpackresponse.py +13 -0
- cribl_control_plane/models/workertypes.py +2 -1
- cribl_control_plane/nodes.py +5 -3
- cribl_control_plane/packs.py +202 -7
- cribl_control_plane/pipelines.py +18 -18
- cribl_control_plane/routes_sdk.py +22 -22
- cribl_control_plane/sdk.py +19 -6
- cribl_control_plane/sources.py +5 -3
- cribl_control_plane/tokens.py +23 -15
- cribl_control_plane/utils/__init__.py +15 -3
- cribl_control_plane/utils/annotations.py +32 -8
- cribl_control_plane/utils/eventstreaming.py +10 -0
- cribl_control_plane/utils/retries.py +69 -5
- cribl_control_plane/utils/unmarshal_json_response.py +15 -1
- cribl_control_plane/versions.py +11 -6
- {cribl_control_plane-0.0.38.dist-info → cribl_control_plane-0.4.0a6.dist-info}/METADATA +69 -23
- cribl_control_plane-0.4.0a6.dist-info/RECORD +336 -0
- {cribl_control_plane-0.0.38.dist-info → cribl_control_plane-0.4.0a6.dist-info}/WHEEL +1 -1
- cribl_control_plane-0.4.0a6.dist-info/licenses/LICENSE +201 -0
- cribl_control_plane/errors/healthstatus_error.py +0 -32
- cribl_control_plane/models/appmode.py +0 -13
- cribl_control_plane/models/healthstatus.py +0 -33
- cribl_control_plane-0.0.38.dist-info/RECORD +0 -315
|
@@ -21,6 +21,7 @@ class Credentials:
|
|
|
21
21
|
client_id: str
|
|
22
22
|
client_secret: str
|
|
23
23
|
token_url: str
|
|
24
|
+
scopes: Optional[List[str]]
|
|
24
25
|
additional_properties: Dict[str, str]
|
|
25
26
|
|
|
26
27
|
def __init__(
|
|
@@ -28,25 +29,27 @@ class Credentials:
|
|
|
28
29
|
client_id: str,
|
|
29
30
|
client_secret: str,
|
|
30
31
|
token_url: str,
|
|
32
|
+
scopes: Optional[List[str]],
|
|
31
33
|
additional_properties: Optional[Dict[str, str]] = None,
|
|
32
34
|
):
|
|
33
35
|
self.client_id = client_id
|
|
34
36
|
self.client_secret = client_secret
|
|
35
37
|
self.token_url = token_url
|
|
38
|
+
self.scopes = scopes
|
|
36
39
|
self.additional_properties = additional_properties or {}
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
class Session:
|
|
40
43
|
credentials: Credentials
|
|
41
44
|
token: str
|
|
42
|
-
scopes:
|
|
45
|
+
scopes: List[str]
|
|
43
46
|
expires_at: Optional[int] = None
|
|
44
47
|
|
|
45
48
|
def __init__(
|
|
46
49
|
self,
|
|
47
50
|
credentials: Credentials,
|
|
48
51
|
token: str,
|
|
49
|
-
scopes:
|
|
52
|
+
scopes: List[str],
|
|
50
53
|
expires_at: Optional[int] = None,
|
|
51
54
|
):
|
|
52
55
|
self.credentials = credentials
|
|
@@ -57,7 +60,7 @@ class Session:
|
|
|
57
60
|
|
|
58
61
|
class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
59
62
|
client: HttpClient
|
|
60
|
-
sessions: Dict[str, Session] = {}
|
|
63
|
+
sessions: Dict[str, Dict[str, Session]] = {}
|
|
61
64
|
|
|
62
65
|
def sdk_init(self, config: SDKConfiguration) -> SDKConfiguration:
|
|
63
66
|
if config.client is None:
|
|
@@ -69,8 +72,7 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
69
72
|
def before_request(
|
|
70
73
|
self, hook_ctx: BeforeRequestContext, request: httpx.Request
|
|
71
74
|
) -> httpx.Request:
|
|
72
|
-
if hook_ctx
|
|
73
|
-
# OAuth2 not in use
|
|
75
|
+
if self.is_hook_disabled(hook_ctx):
|
|
74
76
|
return request
|
|
75
77
|
|
|
76
78
|
credentials = self.get_credentials(hook_ctx)
|
|
@@ -81,22 +83,24 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
81
83
|
credentials.client_id, credentials.client_secret
|
|
82
84
|
)
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
):
|
|
91
|
-
sess = self.do_token_request(
|
|
86
|
+
scopes = self.get_required_scopes(credentials, hook_ctx)
|
|
87
|
+
session = self.get_existing_session(session_key, scopes)
|
|
88
|
+
|
|
89
|
+
if session is None:
|
|
90
|
+
# Create new session
|
|
91
|
+
session = self.do_token_request(
|
|
92
92
|
hook_ctx,
|
|
93
93
|
credentials,
|
|
94
|
-
|
|
94
|
+
scopes,
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
self.sessions
|
|
97
|
+
if session_key not in self.sessions:
|
|
98
|
+
self.sessions[session_key] = {}
|
|
99
|
+
|
|
100
|
+
scope_key = self.get_scope_key(scopes)
|
|
101
|
+
self.sessions[session_key][scope_key] = session
|
|
98
102
|
|
|
99
|
-
request.headers["Authorization"] = f"Bearer {
|
|
103
|
+
request.headers["Authorization"] = f"Bearer {session.token}"
|
|
100
104
|
|
|
101
105
|
return request
|
|
102
106
|
|
|
@@ -106,8 +110,7 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
106
110
|
response: Optional[httpx.Response],
|
|
107
111
|
error: Optional[Exception],
|
|
108
112
|
) -> Union[Tuple[Optional[httpx.Response], Optional[Exception]], Exception]:
|
|
109
|
-
if hook_ctx
|
|
110
|
-
# OAuth2 not in use
|
|
113
|
+
if self.is_hook_disabled(hook_ctx):
|
|
111
114
|
return (response, error)
|
|
112
115
|
|
|
113
116
|
# We don't want to refresh the token if the error is not related to the token
|
|
@@ -122,12 +125,15 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
122
125
|
session_key = self.get_session_key(
|
|
123
126
|
credentials.client_id, credentials.client_secret
|
|
124
127
|
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
scopes = self.get_required_scopes(credentials, hook_ctx)
|
|
129
|
+
scope_key = self.get_scope_key(scopes)
|
|
130
|
+
self.remove_session(session_key, scope_key)
|
|
128
131
|
|
|
129
132
|
return (response, error)
|
|
130
133
|
|
|
134
|
+
def is_hook_disabled(self, hook_ctx: HookContext) -> bool:
|
|
135
|
+
return hook_ctx.oauth2_scopes is None
|
|
136
|
+
|
|
131
137
|
def get_credentials(self, hook_ctx: HookContext) -> Optional[Credentials]:
|
|
132
138
|
source = hook_ctx.security_source
|
|
133
139
|
|
|
@@ -145,21 +151,19 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
145
151
|
# Extract additional properties from security object
|
|
146
152
|
additional_properties = {}
|
|
147
153
|
for key, value in dict(security.client_oauth).items():
|
|
148
|
-
if key not in ["client_id", "client_secret", "token_url"]:
|
|
154
|
+
if key not in ["client_id", "client_secret", "token_url", "scopes"]:
|
|
149
155
|
additional_properties[key] = value
|
|
150
156
|
|
|
151
157
|
return Credentials(
|
|
152
158
|
client_id=security.client_oauth.client_id,
|
|
153
159
|
client_secret=security.client_oauth.client_secret,
|
|
154
160
|
token_url=security.client_oauth.token_url,
|
|
161
|
+
scopes=None,
|
|
155
162
|
additional_properties=additional_properties,
|
|
156
163
|
)
|
|
157
164
|
|
|
158
165
|
def do_token_request(
|
|
159
|
-
self,
|
|
160
|
-
hook_ctx: HookContext,
|
|
161
|
-
credentials: Credentials,
|
|
162
|
-
scopes: Optional[List[str]],
|
|
166
|
+
self, hook_ctx: HookContext, credentials: Credentials, scopes: List[str]
|
|
163
167
|
) -> Session:
|
|
164
168
|
payload = {
|
|
165
169
|
"grant_type": "client_credentials",
|
|
@@ -167,7 +171,7 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
167
171
|
"client_secret": credentials.client_secret,
|
|
168
172
|
}
|
|
169
173
|
|
|
170
|
-
if
|
|
174
|
+
if len(scopes) > 0:
|
|
171
175
|
payload["scope"] = " ".join(scopes)
|
|
172
176
|
|
|
173
177
|
# Add additional properties to payload
|
|
@@ -188,7 +192,7 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
188
192
|
|
|
189
193
|
response_data = response.json()
|
|
190
194
|
|
|
191
|
-
if response_data.get("token_type") != "
|
|
195
|
+
if response_data.get("token_type", "").lower() != "bearer":
|
|
192
196
|
raise Exception("Unexpected token type from token endpoint")
|
|
193
197
|
|
|
194
198
|
expires_at = None
|
|
@@ -203,24 +207,70 @@ class ClientCredentialsHook(SDKInitHook, BeforeRequestHook, AfterErrorHook):
|
|
|
203
207
|
)
|
|
204
208
|
|
|
205
209
|
def get_session_key(self, client_id: str, client_secret: str) -> str:
|
|
210
|
+
"""Generate a consistent session key for the given client ID and secret."""
|
|
206
211
|
return hashlib.md5(f"{client_id}:{client_secret}".encode()).hexdigest()
|
|
207
212
|
|
|
213
|
+
def get_required_scopes(
|
|
214
|
+
self, credentials: Credentials, hook_ctx: HookContext
|
|
215
|
+
) -> List[str]:
|
|
216
|
+
"""Return the list of scopes that need to be requested."""
|
|
217
|
+
if credentials.scopes is not None:
|
|
218
|
+
return credentials.scopes
|
|
219
|
+
return hook_ctx.oauth2_scopes or []
|
|
220
|
+
|
|
221
|
+
def get_scope_key(self, scopes: List[str]) -> str:
|
|
222
|
+
"""Generate a consistent scope key for the given scopes."""
|
|
223
|
+
if not scopes:
|
|
224
|
+
return ""
|
|
225
|
+
|
|
226
|
+
sorted_scopes = sorted(scopes)
|
|
227
|
+
return "&".join(sorted_scopes)
|
|
228
|
+
|
|
229
|
+
def remove_session(self, client_key: str, scope_key: str) -> None:
|
|
230
|
+
"""Remove a session and clean up empty client session maps."""
|
|
231
|
+
if client_key in self.sessions and scope_key in self.sessions[client_key]:
|
|
232
|
+
del self.sessions[client_key][scope_key]
|
|
233
|
+
|
|
234
|
+
# Clean up empty client sessions
|
|
235
|
+
if not self.sessions[client_key]:
|
|
236
|
+
del self.sessions[client_key]
|
|
237
|
+
|
|
238
|
+
def get_existing_session(
|
|
239
|
+
self, client_key: str, required_scopes: List[str]
|
|
240
|
+
) -> Optional[Session]:
|
|
241
|
+
"""Find the best session for the required scopes."""
|
|
242
|
+
if client_key not in self.sessions:
|
|
243
|
+
return None
|
|
244
|
+
|
|
245
|
+
client_sessions = self.sessions[client_key]
|
|
246
|
+
scope_key = self.get_scope_key(required_scopes)
|
|
247
|
+
|
|
248
|
+
if scope_key in client_sessions:
|
|
249
|
+
exact_match = client_sessions[scope_key]
|
|
250
|
+
if self.has_token_expired(exact_match.expires_at):
|
|
251
|
+
self.remove_session(client_key, scope_key)
|
|
252
|
+
else:
|
|
253
|
+
return exact_match
|
|
254
|
+
|
|
255
|
+
# If no exact match was found, look for a superset match
|
|
256
|
+
for key, session in client_sessions.items():
|
|
257
|
+
if self.has_token_expired(session.expires_at):
|
|
258
|
+
self.remove_session(client_key, key)
|
|
259
|
+
elif self.has_required_scopes(session.scopes, required_scopes):
|
|
260
|
+
return session
|
|
261
|
+
|
|
262
|
+
return None
|
|
263
|
+
|
|
208
264
|
def has_required_scopes(
|
|
209
|
-
self, scopes:
|
|
265
|
+
self, scopes: List[str], required_scopes: List[str]
|
|
210
266
|
) -> bool:
|
|
211
|
-
if scopes
|
|
212
|
-
return False
|
|
213
|
-
|
|
267
|
+
"""Check if all required scopes are present in the given scopes."""
|
|
214
268
|
return all(scope in scopes for scope in required_scopes)
|
|
215
269
|
|
|
216
|
-
def get_scopes(
|
|
217
|
-
self, required_scopes: List[str], sess: Optional[Session]
|
|
218
|
-
) -> List[str]:
|
|
219
|
-
scopes = required_scopes.copy()
|
|
220
|
-
if sess is not None and sess.scopes is not None:
|
|
221
|
-
scopes.extend(sess.scopes)
|
|
222
|
-
scopes = list(set(scopes))
|
|
223
|
-
return scopes
|
|
224
|
-
|
|
225
270
|
def has_token_expired(self, expires_at: Optional[int]) -> bool:
|
|
226
|
-
|
|
271
|
+
"""
|
|
272
|
+
Check if the token has expired.
|
|
273
|
+
If no expires_in field was returned by the authorization server, the token is considered to never expire.
|
|
274
|
+
A 60-second buffer is applied to refresh tokens before they actually expire.
|
|
275
|
+
"""
|
|
276
|
+
return expires_at is not None and time.time() + 60 >= expires_at
|
cribl_control_plane/_version.py
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import importlib.metadata
|
|
4
4
|
|
|
5
5
|
__title__: str = "cribl-control-plane"
|
|
6
|
-
__version__: str = "0.
|
|
7
|
-
__openapi_doc_version__: str = "4.
|
|
8
|
-
__gen_version__: str = "2.
|
|
9
|
-
__user_agent__: str = "speakeasy-sdk/python 0.
|
|
6
|
+
__version__: str = "0.4.0a6"
|
|
7
|
+
__openapi_doc_version__: str = "4.15.0-alpha.1763072414698-97546d75"
|
|
8
|
+
__gen_version__: str = "2.763.3"
|
|
9
|
+
__user_agent__: str = "speakeasy-sdk/python 0.4.0a6 2.763.3 4.15.0-alpha.1763072414698-97546d75 cribl-control-plane"
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
12
|
if __package__ is not None:
|
cribl_control_plane/acl.py
CHANGED
|
@@ -14,13 +14,15 @@ from typing import Any, Mapping, Optional
|
|
|
14
14
|
class ACL(BaseSDK):
|
|
15
15
|
teams: Teams
|
|
16
16
|
|
|
17
|
-
def __init__(
|
|
18
|
-
|
|
17
|
+
def __init__(
|
|
18
|
+
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
|
|
19
|
+
) -> None:
|
|
20
|
+
BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
|
|
19
21
|
self.sdk_configuration = sdk_config
|
|
20
22
|
self._init_sdks()
|
|
21
23
|
|
|
22
24
|
def _init_sdks(self):
|
|
23
|
-
self.teams = Teams(self.sdk_configuration)
|
|
25
|
+
self.teams = Teams(self.sdk_configuration, parent_ref=self.parent_ref)
|
|
24
26
|
|
|
25
27
|
def get(
|
|
26
28
|
self,
|
cribl_control_plane/auth_sdk.py
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
from .basesdk import BaseSDK
|
|
4
4
|
from .sdkconfiguration import SDKConfiguration
|
|
5
5
|
from cribl_control_plane.tokens import Tokens
|
|
6
|
+
from typing import Optional
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class AuthSDK(BaseSDK):
|
|
9
10
|
tokens: Tokens
|
|
10
11
|
|
|
11
|
-
def __init__(
|
|
12
|
-
|
|
12
|
+
def __init__(
|
|
13
|
+
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
|
|
14
|
+
) -> None:
|
|
15
|
+
BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
|
|
13
16
|
self.sdk_configuration = sdk_config
|
|
14
17
|
self._init_sdks()
|
|
15
18
|
|
|
16
19
|
def _init_sdks(self):
|
|
17
|
-
self.tokens = Tokens(self.sdk_configuration)
|
|
20
|
+
self.tokens = Tokens(self.sdk_configuration, parent_ref=self.parent_ref)
|
cribl_control_plane/basesdk.py
CHANGED
|
@@ -19,9 +19,19 @@ from urllib.parse import parse_qs, urlparse
|
|
|
19
19
|
|
|
20
20
|
class BaseSDK:
|
|
21
21
|
sdk_configuration: SDKConfiguration
|
|
22
|
+
parent_ref: Optional[object] = None
|
|
23
|
+
"""
|
|
24
|
+
Reference to the root SDK instance, if any. This will prevent it from
|
|
25
|
+
being garbage collected while there are active streams.
|
|
26
|
+
"""
|
|
22
27
|
|
|
23
|
-
def __init__(
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
sdk_config: SDKConfiguration,
|
|
31
|
+
parent_ref: Optional[object] = None,
|
|
32
|
+
) -> None:
|
|
24
33
|
self.sdk_configuration = sdk_config
|
|
34
|
+
self.parent_ref = parent_ref
|
|
25
35
|
|
|
26
36
|
def _get_url(self, base_url, url_variables):
|
|
27
37
|
sdk_url, sdk_variables = self.sdk_configuration.get_server_details()
|
cribl_control_plane/commits.py
CHANGED
|
@@ -14,13 +14,15 @@ from typing import Any, List, Mapping, Optional
|
|
|
14
14
|
class Commits(BaseSDK):
|
|
15
15
|
files: CommitsFiles
|
|
16
16
|
|
|
17
|
-
def __init__(
|
|
18
|
-
|
|
17
|
+
def __init__(
|
|
18
|
+
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
|
|
19
|
+
) -> None:
|
|
20
|
+
BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
|
|
19
21
|
self.sdk_configuration = sdk_config
|
|
20
22
|
self._init_sdks()
|
|
21
23
|
|
|
22
24
|
def _init_sdks(self):
|
|
23
|
-
self.files = CommitsFiles(self.sdk_configuration)
|
|
25
|
+
self.files = CommitsFiles(self.sdk_configuration, parent_ref=self.parent_ref)
|
|
24
26
|
|
|
25
27
|
def create(
|
|
26
28
|
self,
|
|
@@ -779,7 +781,7 @@ class Commits(BaseSDK):
|
|
|
779
781
|
Revert a commit in the local repository.
|
|
780
782
|
|
|
781
783
|
:param commit:
|
|
782
|
-
:param group_id: Group
|
|
784
|
+
:param group_id: The <code>id</code> of the Worker Group or Edge Fleet to revert the commit for. Required in Distributed deployments. Omit in Single-instance deployments.
|
|
783
785
|
:param force:
|
|
784
786
|
:param message:
|
|
785
787
|
:param retries: Override the default retry configuration for this method
|
|
@@ -880,7 +882,7 @@ class Commits(BaseSDK):
|
|
|
880
882
|
Revert a commit in the local repository.
|
|
881
883
|
|
|
882
884
|
:param commit:
|
|
883
|
-
:param group_id: Group
|
|
885
|
+
:param group_id: The <code>id</code> of the Worker Group or Edge Fleet to revert the commit for. Required in Distributed deployments. Omit in Single-instance deployments.
|
|
884
886
|
:param force:
|
|
885
887
|
:param message:
|
|
886
888
|
:param retries: Override the default retry configuration for this method
|
|
@@ -18,14 +18,16 @@ class Destinations(BaseSDK):
|
|
|
18
18
|
pq: DestinationsPq
|
|
19
19
|
samples: Samples
|
|
20
20
|
|
|
21
|
-
def __init__(
|
|
22
|
-
|
|
21
|
+
def __init__(
|
|
22
|
+
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
|
|
23
|
+
) -> None:
|
|
24
|
+
BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
|
|
23
25
|
self.sdk_configuration = sdk_config
|
|
24
26
|
self._init_sdks()
|
|
25
27
|
|
|
26
28
|
def _init_sdks(self):
|
|
27
|
-
self.pq = DestinationsPq(self.sdk_configuration)
|
|
28
|
-
self.samples = Samples(self.sdk_configuration)
|
|
29
|
+
self.pq = DestinationsPq(self.sdk_configuration, parent_ref=self.parent_ref)
|
|
30
|
+
self.samples = Samples(self.sdk_configuration, parent_ref=self.parent_ref)
|
|
29
31
|
|
|
30
32
|
def list(
|
|
31
33
|
self,
|
|
@@ -83,7 +83,7 @@ class DestinationsPq(BaseSDK):
|
|
|
83
83
|
)
|
|
84
84
|
|
|
85
85
|
response_data: Any = None
|
|
86
|
-
if utils.match_response(http_res, "
|
|
86
|
+
if utils.match_response(http_res, "201", "application/json"):
|
|
87
87
|
return unmarshal_json_response(models.DeleteOutputPqByIDResponse, http_res)
|
|
88
88
|
if utils.match_response(http_res, "500", "application/json"):
|
|
89
89
|
response_data = unmarshal_json_response(errors.ErrorData, http_res)
|
|
@@ -170,7 +170,7 @@ class DestinationsPq(BaseSDK):
|
|
|
170
170
|
)
|
|
171
171
|
|
|
172
172
|
response_data: Any = None
|
|
173
|
-
if utils.match_response(http_res, "
|
|
173
|
+
if utils.match_response(http_res, "201", "application/json"):
|
|
174
174
|
return unmarshal_json_response(models.DeleteOutputPqByIDResponse, http_res)
|
|
175
175
|
if utils.match_response(http_res, "500", "application/json"):
|
|
176
176
|
response_data = unmarshal_json_response(errors.ErrorData, http_res)
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
2
|
|
|
3
|
+
from .criblcontrolplaneerror import CriblControlPlaneError
|
|
3
4
|
from typing import TYPE_CHECKING
|
|
4
5
|
from importlib import import_module
|
|
5
6
|
import builtins
|
|
7
|
+
import sys
|
|
6
8
|
|
|
7
9
|
if TYPE_CHECKING:
|
|
8
10
|
from .apierror import APIError
|
|
9
|
-
from .criblcontrolplaneerror import CriblControlPlaneError
|
|
10
11
|
from .error import Error, ErrorData
|
|
11
|
-
from .
|
|
12
|
+
from .healthserverstatus_error import (
|
|
13
|
+
HealthServerStatusError,
|
|
14
|
+
HealthServerStatusErrorData,
|
|
15
|
+
)
|
|
12
16
|
from .no_response_error import NoResponseError
|
|
13
17
|
from .responsevalidationerror import ResponseValidationError
|
|
14
18
|
|
|
@@ -17,24 +21,35 @@ __all__ = [
|
|
|
17
21
|
"CriblControlPlaneError",
|
|
18
22
|
"Error",
|
|
19
23
|
"ErrorData",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
24
|
+
"HealthServerStatusError",
|
|
25
|
+
"HealthServerStatusErrorData",
|
|
22
26
|
"NoResponseError",
|
|
23
27
|
"ResponseValidationError",
|
|
24
28
|
]
|
|
25
29
|
|
|
26
30
|
_dynamic_imports: dict[str, str] = {
|
|
27
31
|
"APIError": ".apierror",
|
|
28
|
-
"CriblControlPlaneError": ".criblcontrolplaneerror",
|
|
29
32
|
"Error": ".error",
|
|
30
33
|
"ErrorData": ".error",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
34
|
+
"HealthServerStatusError": ".healthserverstatus_error",
|
|
35
|
+
"HealthServerStatusErrorData": ".healthserverstatus_error",
|
|
33
36
|
"NoResponseError": ".no_response_error",
|
|
34
37
|
"ResponseValidationError": ".responsevalidationerror",
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
|
|
41
|
+
def dynamic_import(modname, retries=3):
|
|
42
|
+
for attempt in range(retries):
|
|
43
|
+
try:
|
|
44
|
+
return import_module(modname, __package__)
|
|
45
|
+
except KeyError:
|
|
46
|
+
# Clear any half-initialized module and retry
|
|
47
|
+
sys.modules.pop(modname, None)
|
|
48
|
+
if attempt == retries - 1:
|
|
49
|
+
break
|
|
50
|
+
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
|
|
51
|
+
|
|
52
|
+
|
|
38
53
|
def __getattr__(attr_name: str) -> object:
|
|
39
54
|
module_name = _dynamic_imports.get(attr_name)
|
|
40
55
|
if module_name is None:
|
|
@@ -43,7 +58,7 @@ def __getattr__(attr_name: str) -> object:
|
|
|
43
58
|
)
|
|
44
59
|
|
|
45
60
|
try:
|
|
46
|
-
module =
|
|
61
|
+
module = dynamic_import(module_name)
|
|
47
62
|
result = getattr(module, attr_name)
|
|
48
63
|
return result
|
|
49
64
|
except ImportError as e:
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import httpx
|
|
4
4
|
from typing import Optional
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
|
|
6
7
|
from cribl_control_plane.errors import CriblControlPlaneError
|
|
7
8
|
|
|
8
9
|
MAX_MESSAGE_LEN = 10_000
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
@dataclass(unsafe_hash=True)
|
|
11
13
|
class APIError(CriblControlPlaneError):
|
|
12
14
|
"""The fallback error class if no more specific error class is matched."""
|
|
13
15
|
|
|
@@ -2,25 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
import httpx
|
|
4
4
|
from typing import Optional
|
|
5
|
+
from dataclasses import dataclass, field
|
|
5
6
|
|
|
6
7
|
|
|
8
|
+
@dataclass(unsafe_hash=True)
|
|
7
9
|
class CriblControlPlaneError(Exception):
|
|
8
10
|
"""The base class for all HTTP error responses."""
|
|
9
11
|
|
|
10
12
|
message: str
|
|
11
13
|
status_code: int
|
|
12
14
|
body: str
|
|
13
|
-
headers: httpx.Headers
|
|
14
|
-
raw_response: httpx.Response
|
|
15
|
+
headers: httpx.Headers = field(hash=False)
|
|
16
|
+
raw_response: httpx.Response = field(hash=False)
|
|
15
17
|
|
|
16
18
|
def __init__(
|
|
17
19
|
self, message: str, raw_response: httpx.Response, body: Optional[str] = None
|
|
18
20
|
):
|
|
19
|
-
self
|
|
20
|
-
self
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
object.__setattr__(self, "message", message)
|
|
22
|
+
object.__setattr__(self, "status_code", raw_response.status_code)
|
|
23
|
+
object.__setattr__(
|
|
24
|
+
self, "body", body if body is not None else raw_response.text
|
|
25
|
+
)
|
|
26
|
+
object.__setattr__(self, "headers", raw_response.headers)
|
|
27
|
+
object.__setattr__(self, "raw_response", raw_response)
|
|
24
28
|
|
|
25
29
|
def __str__(self):
|
|
26
30
|
return self.message
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
from cribl_control_plane.errors import CriblControlPlaneError
|
|
5
5
|
from cribl_control_plane.types import BaseModel
|
|
6
|
+
from dataclasses import dataclass, field
|
|
6
7
|
import httpx
|
|
7
8
|
from typing import Optional
|
|
8
9
|
|
|
@@ -12,8 +13,9 @@ class ErrorData(BaseModel):
|
|
|
12
13
|
r"""Error message"""
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
@dataclass(unsafe_hash=True)
|
|
15
17
|
class Error(CriblControlPlaneError):
|
|
16
|
-
data: ErrorData
|
|
18
|
+
data: ErrorData = field(hash=False)
|
|
17
19
|
|
|
18
20
|
def __init__(
|
|
19
21
|
self, data: ErrorData, raw_response: httpx.Response, body: Optional[str] = None
|
|
@@ -21,4 +23,4 @@ class Error(CriblControlPlaneError):
|
|
|
21
23
|
fallback = body or raw_response.text
|
|
22
24
|
message = str(data.message) or fallback
|
|
23
25
|
super().__init__(message, raw_response, body)
|
|
24
|
-
self
|
|
26
|
+
object.__setattr__(self, "data", data)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from cribl_control_plane.errors import CriblControlPlaneError
|
|
5
|
+
from cribl_control_plane.models import healthserverstatus as models_healthserverstatus
|
|
6
|
+
from cribl_control_plane.types import BaseModel
|
|
7
|
+
from cribl_control_plane.utils import validate_open_enum
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
import httpx
|
|
10
|
+
import pydantic
|
|
11
|
+
from pydantic.functional_validators import PlainValidator
|
|
12
|
+
from typing import Optional
|
|
13
|
+
from typing_extensions import Annotated
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class HealthServerStatusErrorData(BaseModel):
|
|
17
|
+
start_time: Annotated[float, pydantic.Field(alias="startTime")]
|
|
18
|
+
|
|
19
|
+
status: Annotated[
|
|
20
|
+
models_healthserverstatus.Status, PlainValidator(validate_open_enum(False))
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
role: Annotated[
|
|
24
|
+
Optional[models_healthserverstatus.Role],
|
|
25
|
+
PlainValidator(validate_open_enum(False)),
|
|
26
|
+
] = None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(unsafe_hash=True)
|
|
30
|
+
class HealthServerStatusError(CriblControlPlaneError):
|
|
31
|
+
data: HealthServerStatusErrorData = field(hash=False)
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
data: HealthServerStatusErrorData,
|
|
36
|
+
raw_response: httpx.Response,
|
|
37
|
+
body: Optional[str] = None,
|
|
38
|
+
):
|
|
39
|
+
message = body or raw_response.text
|
|
40
|
+
super().__init__(message, raw_response, body)
|
|
41
|
+
object.__setattr__(self, "data", data)
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
|
|
2
2
|
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(unsafe_hash=True)
|
|
3
7
|
class NoResponseError(Exception):
|
|
4
8
|
"""Error raised when no HTTP response is received from the server."""
|
|
5
9
|
|
|
6
10
|
message: str
|
|
7
11
|
|
|
8
12
|
def __init__(self, message: str = "No response received"):
|
|
9
|
-
self
|
|
13
|
+
object.__setattr__(self, "message", message)
|
|
10
14
|
super().__init__(message)
|
|
11
15
|
|
|
12
16
|
def __str__(self):
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import httpx
|
|
4
4
|
from typing import Optional
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
|
|
6
7
|
from cribl_control_plane.errors import CriblControlPlaneError
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
@dataclass(unsafe_hash=True)
|
|
9
11
|
class ResponseValidationError(CriblControlPlaneError):
|
|
10
12
|
"""Error raised when there is a type mismatch between the response data and the expected Pydantic model."""
|
|
11
13
|
|
|
@@ -3,15 +3,20 @@
|
|
|
3
3
|
from .basesdk import BaseSDK
|
|
4
4
|
from .sdkconfiguration import SDKConfiguration
|
|
5
5
|
from cribl_control_plane.configs_versions import ConfigsVersions
|
|
6
|
+
from typing import Optional
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class GroupsConfigs(BaseSDK):
|
|
9
10
|
versions: ConfigsVersions
|
|
10
11
|
|
|
11
|
-
def __init__(
|
|
12
|
-
|
|
12
|
+
def __init__(
|
|
13
|
+
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
|
|
14
|
+
) -> None:
|
|
15
|
+
BaseSDK.__init__(self, sdk_config, parent_ref=parent_ref)
|
|
13
16
|
self.sdk_configuration = sdk_config
|
|
14
17
|
self._init_sdks()
|
|
15
18
|
|
|
16
19
|
def _init_sdks(self):
|
|
17
|
-
self.versions = ConfigsVersions(
|
|
20
|
+
self.versions = ConfigsVersions(
|
|
21
|
+
self.sdk_configuration, parent_ref=self.parent_ref
|
|
22
|
+
)
|