zosmfrestapi 0.2.0__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.
- zosmfrestapi/__init__.py +93 -0
- zosmfrestapi/client.py +47 -0
- zosmfrestapi/exceptions/__init__.py +18 -0
- zosmfrestapi/exceptions/authentication.py +17 -0
- zosmfrestapi/exceptions/dataset.py +17 -0
- zosmfrestapi/exceptions/software.py +34 -0
- zosmfrestapi/exceptions/workflow.py +30 -0
- zosmfrestapi/models/__init__.py +0 -0
- zosmfrestapi/models/authentication.py +16 -0
- zosmfrestapi/models/software.py +231 -0
- zosmfrestapi/models/software_updates.py +99 -0
- zosmfrestapi/models/topology.py +28 -0
- zosmfrestapi/models/workflow.py +114 -0
- zosmfrestapi/py.typed +0 -0
- zosmfrestapi/services/__init__.py +176 -0
- zosmfrestapi/services/authentication.py +52 -0
- zosmfrestapi/services/dataset.py +42 -0
- zosmfrestapi/services/software.py +477 -0
- zosmfrestapi/services/software_updates.py +949 -0
- zosmfrestapi/services/topology.py +49 -0
- zosmfrestapi/services/workflow.py +350 -0
- zosmfrestapi/testing/__init__.py +11 -0
- zosmfrestapi/testing/authentication.py +48 -0
- zosmfrestapi/testing/helpers.py +9 -0
- zosmfrestapi/testing/software.py +392 -0
- zosmfrestapi/testing/software_updates.py +281 -0
- zosmfrestapi/testing/topology.py +19 -0
- zosmfrestapi/testing/workflows.py +320 -0
- zosmfrestapi/utils.py +76 -0
- zosmfrestapi/zcrypto.py +55 -0
- zosmfrestapi/zcrypto_client.py +68 -0
- zosmfrestapi-0.2.0.dist-info/METADATA +172 -0
- zosmfrestapi-0.2.0.dist-info/RECORD +35 -0
- zosmfrestapi-0.2.0.dist-info/WHEEL +4 -0
- zosmfrestapi-0.2.0.dist-info/licenses/LICENSE +10 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from typing import Any
|
|
4
|
+
from dataclasses import asdict
|
|
5
|
+
|
|
6
|
+
import pendulum
|
|
7
|
+
from dacite import Config, from_dict
|
|
8
|
+
|
|
9
|
+
from zosmfrestapi.exceptions.software import (
|
|
10
|
+
ZosmfSoftwareInstanceNotFoundError,
|
|
11
|
+
ZosmfSoftwareManagementError,
|
|
12
|
+
ZosmfSoftwareManagementRequestError,
|
|
13
|
+
)
|
|
14
|
+
from zosmfrestapi.models.software import (
|
|
15
|
+
CsiEntry,
|
|
16
|
+
DataSet,
|
|
17
|
+
DataSetProperty,
|
|
18
|
+
DataSetPropertyLabel,
|
|
19
|
+
NonSmpeManagedDataset,
|
|
20
|
+
NonSmpeProduct,
|
|
21
|
+
Product,
|
|
22
|
+
ProductProperty,
|
|
23
|
+
SmpeManagedDataset,
|
|
24
|
+
SmpeManagedUnixDataset,
|
|
25
|
+
SoftwareInstance,
|
|
26
|
+
SoftwareInstanceWorkflow,
|
|
27
|
+
)
|
|
28
|
+
from zosmfrestapi.utils import _parse_datetime, remap
|
|
29
|
+
|
|
30
|
+
from . import ZosmfBase
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class SoftwareServices(ZosmfBase):
|
|
36
|
+
"""Manage z/OSMF software instances and query their SMP/E CSI data."""
|
|
37
|
+
|
|
38
|
+
def list_swis(self) -> list[SoftwareInstance]:
|
|
39
|
+
"""List the software instances available on the z/OSMF server.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
A list of ``SoftwareInstance`` objects.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
46
|
+
ZosmfError: If z/OSMF returns another unsuccessful HTTP status.
|
|
47
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
48
|
+
is received.
|
|
49
|
+
"""
|
|
50
|
+
resp = self.http.get("/zosmf/swmgmt/swi")
|
|
51
|
+
self._raise_for_status(resp)
|
|
52
|
+
return [
|
|
53
|
+
from_dict(
|
|
54
|
+
data_class=SoftwareInstance,
|
|
55
|
+
data=remap(swi, SoftwareInstance),
|
|
56
|
+
config=Config(
|
|
57
|
+
type_hooks={
|
|
58
|
+
pendulum.DateTime: _parse_datetime,
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
for swi in resp.json()["swilist"]
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
def _get_swi(self, path: str) -> SoftwareInstance:
|
|
66
|
+
resp = self.http.get(path)
|
|
67
|
+
if resp.status_code == 404:
|
|
68
|
+
raise ZosmfSoftwareInstanceNotFoundError(resp)
|
|
69
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementError)
|
|
70
|
+
return from_dict(
|
|
71
|
+
data_class=SoftwareInstance,
|
|
72
|
+
data=remap(resp.json(), SoftwareInstance),
|
|
73
|
+
config=Config(
|
|
74
|
+
type_hooks={
|
|
75
|
+
pendulum.DateTime: _parse_datetime,
|
|
76
|
+
list[DataSet]: lambda v: [] if v is None else v,
|
|
77
|
+
list[Product]: lambda v: [] if v is None else v,
|
|
78
|
+
list[NonSmpeProduct]: lambda v: [] if v is None else v,
|
|
79
|
+
list[SoftwareInstanceWorkflow]: lambda v: [] if v is None else v,
|
|
80
|
+
list[DataSetProperty]: lambda v: [] if v is None else v,
|
|
81
|
+
list[DataSetPropertyLabel]: lambda v: [] if v is None else v,
|
|
82
|
+
list[ProductProperty]: lambda v: [] if v is None else v,
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def get_swi_by_uuid(self, swiuuid: str) -> SoftwareInstance:
|
|
88
|
+
"""Retrieve a software instance by UUID.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
swiuuid: UUID of the software instance.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
The matching ``SoftwareInstance``.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
98
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
99
|
+
ZosmfSoftwareManagementError: If z/OSMF returns another
|
|
100
|
+
unsuccessful HTTP status.
|
|
101
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
102
|
+
is received.
|
|
103
|
+
"""
|
|
104
|
+
return self._get_swi(f"/zosmf/swmgmt/swi/{swiuuid}")
|
|
105
|
+
|
|
106
|
+
def get_swi_by_name(self, name: str, system: str) -> SoftwareInstance:
|
|
107
|
+
"""Retrieve a software instance by name and system.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
name: Name of the software instance.
|
|
111
|
+
system: System where the software instance is defined.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The matching ``SoftwareInstance``.
|
|
115
|
+
|
|
116
|
+
Raises:
|
|
117
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
118
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
119
|
+
ZosmfSoftwareManagementError: If z/OSMF returns another
|
|
120
|
+
unsuccessful HTTP status.
|
|
121
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
122
|
+
is received.
|
|
123
|
+
"""
|
|
124
|
+
return self._get_swi(f"/zosmf/swmgmt/swi/{system}/{name}")
|
|
125
|
+
|
|
126
|
+
def _get_swi_datasets(self, path: str) -> dict[
|
|
127
|
+
str,
|
|
128
|
+
list[SmpeManagedDataset] | list[SmpeManagedUnixDataset] | list[NonSmpeManagedDataset],
|
|
129
|
+
]:
|
|
130
|
+
resp = self.http.post(path)
|
|
131
|
+
if resp.status_code == 404:
|
|
132
|
+
raise ZosmfSoftwareInstanceNotFoundError(resp)
|
|
133
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementError)
|
|
134
|
+
status_monitor_url = resp.json()["statusurl"]
|
|
135
|
+
status = self.http.get(status_monitor_url)
|
|
136
|
+
while status.json()["status"] == "running":
|
|
137
|
+
time.sleep(2)
|
|
138
|
+
status = self.http.get(status_monitor_url)
|
|
139
|
+
self._raise_for_status(status, exc_handler=ZosmfSoftwareManagementError)
|
|
140
|
+
return {
|
|
141
|
+
"smpemanageddatasets": [
|
|
142
|
+
from_dict(data_class=SmpeManagedDataset, data=dataset)
|
|
143
|
+
for dataset in status.json()["smpemanageddatasets"] or []
|
|
144
|
+
],
|
|
145
|
+
"smpemanagedunixdatasets": [
|
|
146
|
+
from_dict(data_class=SmpeManagedUnixDataset, data=missing)
|
|
147
|
+
for missing in status.json()["smpemanagedunixdatasets"] or []
|
|
148
|
+
],
|
|
149
|
+
"nonsmpemanageddatasets": [
|
|
150
|
+
from_dict(data_class=NonSmpeManagedDataset, data=missing)
|
|
151
|
+
for missing in status.json()["nonsmpemanageddatasets"] or []
|
|
152
|
+
],
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
def get_swi_datasets_by_uuid(self, swiuuid: str) -> dict[
|
|
156
|
+
str,
|
|
157
|
+
list[SmpeManagedDataset] | list[SmpeManagedUnixDataset] | list[NonSmpeManagedDataset],
|
|
158
|
+
]:
|
|
159
|
+
"""Retrieve dataset inventories for a software instance by UUID.
|
|
160
|
+
|
|
161
|
+
z/OSMF processes this request asynchronously; this method polls its
|
|
162
|
+
status endpoint until the inventory is ready.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
swiuuid: UUID of the software instance.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
A dictionary with ``smpemanageddatasets``,
|
|
169
|
+
``smpemanagedunixdatasets``, and ``nonsmpemanageddatasets`` keys.
|
|
170
|
+
Each value is a list of the corresponding parsed dataset model.
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
174
|
+
ZosmfAuthError: If a request returns HTTP 401.
|
|
175
|
+
ZosmfSoftwareManagementRequestError: If a request returns another
|
|
176
|
+
unsuccessful HTTP status.
|
|
177
|
+
httpx2.RequestError: If a request fails before an HTTP response is
|
|
178
|
+
received.
|
|
179
|
+
"""
|
|
180
|
+
return self._get_swi_datasets(f"/zosmf/swmgmt/swi/{swiuuid}/datasets")
|
|
181
|
+
|
|
182
|
+
def get_swi_datasets_by_name(self, name: str, system: str) -> dict[
|
|
183
|
+
str,
|
|
184
|
+
list[SmpeManagedDataset] | list[SmpeManagedUnixDataset] | list[NonSmpeManagedDataset],
|
|
185
|
+
]:
|
|
186
|
+
"""Retrieve dataset inventories for a software instance by name.
|
|
187
|
+
|
|
188
|
+
z/OSMF processes this request asynchronously; this method polls its
|
|
189
|
+
status endpoint until the inventory is ready.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
name: Name of the software instance.
|
|
193
|
+
system: System where the software instance is defined.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
A dictionary with ``smpemanageddatasets``,
|
|
197
|
+
``smpemanagedunixdatasets``, and ``nonsmpemanageddatasets`` keys.
|
|
198
|
+
Each value is a list of the corresponding parsed dataset model.
|
|
199
|
+
|
|
200
|
+
Raises:
|
|
201
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
202
|
+
ZosmfAuthError: If a request returns HTTP 401.
|
|
203
|
+
ZosmfSoftwareManagementRequestError: If a request returns another
|
|
204
|
+
unsuccessful HTTP status.
|
|
205
|
+
httpx2.RequestError: If a request fails before an HTTP response is
|
|
206
|
+
received.
|
|
207
|
+
"""
|
|
208
|
+
return self._get_swi_datasets(f"/zosmf/swmgmt/swi/{system}/{name}/datasets")
|
|
209
|
+
|
|
210
|
+
def add_swi(self, swi: SoftwareInstance) -> bool:
|
|
211
|
+
"""Add a new software instance.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
swi: Validated software-instance data to submit, including its name
|
|
215
|
+
and system and any configured zones, data sets, products, or
|
|
216
|
+
workflows.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
``True`` when z/OSMF responds with HTTP 201; ``False`` for another
|
|
220
|
+
successful response status.
|
|
221
|
+
|
|
222
|
+
Raises:
|
|
223
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
224
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
225
|
+
unsuccessful HTTP status.
|
|
226
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
227
|
+
is received.
|
|
228
|
+
"""
|
|
229
|
+
resp = self.http.post(
|
|
230
|
+
"/zosmf/swmgmt/swi",
|
|
231
|
+
json={
|
|
232
|
+
"name": swi.name,
|
|
233
|
+
"system": swi.system,
|
|
234
|
+
"description": swi.description if swi.description else "",
|
|
235
|
+
"globalzone": swi.globalzone if swi.globalzone else "",
|
|
236
|
+
"targetzones": swi.targetzones if swi.targetzones else [],
|
|
237
|
+
"categories": swi.categories if swi.categories else [],
|
|
238
|
+
"datasets": swi.datasets if swi.datasets else [],
|
|
239
|
+
"products": (
|
|
240
|
+
[
|
|
241
|
+
{
|
|
242
|
+
"prodname": product.prodname,
|
|
243
|
+
"prodid": product.productid,
|
|
244
|
+
"release": product.release,
|
|
245
|
+
"vendor": product.vendor,
|
|
246
|
+
"url": product.url,
|
|
247
|
+
"features": (
|
|
248
|
+
[feature.feature for feature in product.features]
|
|
249
|
+
if product.features
|
|
250
|
+
else []
|
|
251
|
+
),
|
|
252
|
+
"generalavailability": product.generalavailability,
|
|
253
|
+
"endofservice": product.endofservice,
|
|
254
|
+
}
|
|
255
|
+
for product in swi.products
|
|
256
|
+
]
|
|
257
|
+
if swi.products
|
|
258
|
+
else []
|
|
259
|
+
),
|
|
260
|
+
"workflows": (
|
|
261
|
+
[asdict(workflow) for workflow in swi.workflows] if swi.workflows else []
|
|
262
|
+
),
|
|
263
|
+
},
|
|
264
|
+
)
|
|
265
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementRequestError)
|
|
266
|
+
return resp.status_code == 201
|
|
267
|
+
|
|
268
|
+
def _remove_sw_instance(self, path: str) -> bool:
|
|
269
|
+
resp = self.http.delete(path)
|
|
270
|
+
if resp.status_code == 404:
|
|
271
|
+
raise ZosmfSoftwareInstanceNotFoundError(resp)
|
|
272
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementRequestError)
|
|
273
|
+
return resp.status_code == 200
|
|
274
|
+
|
|
275
|
+
def remove_sw_instance_by_uuid(self, swiuuid: str) -> bool:
|
|
276
|
+
"""Delete a software instance identified by UUID.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
swiuuid: UUID of the software instance to delete.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
``True`` when z/OSMF responds with HTTP 200; ``False`` for another
|
|
283
|
+
successful response status.
|
|
284
|
+
|
|
285
|
+
Raises:
|
|
286
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
287
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
288
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
289
|
+
unsuccessful HTTP status.
|
|
290
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
291
|
+
is received.
|
|
292
|
+
"""
|
|
293
|
+
return self._remove_sw_instance(f"/zosmf/swmgmt/swi/{swiuuid}")
|
|
294
|
+
|
|
295
|
+
def remove_sw_instance_by_name(self, name: str, system: str) -> bool:
|
|
296
|
+
"""Delete a software instance identified by name.
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
name: Name of the software instance to delete.
|
|
300
|
+
system: System where the software instance is defined.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
``True`` when z/OSMF responds with HTTP 200; ``False`` for another
|
|
304
|
+
successful response status.
|
|
305
|
+
|
|
306
|
+
Raises:
|
|
307
|
+
ZosmfSoftwareInstanceNotFoundError: If z/OSMF returns HTTP 404.
|
|
308
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
309
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
310
|
+
unsuccessful HTTP status.
|
|
311
|
+
httpx2.RequestError: If the request fails before an HTTP response
|
|
312
|
+
is received.
|
|
313
|
+
"""
|
|
314
|
+
return self._remove_sw_instance(f"/zosmf/swmgmt/swi/{system}/{name}")
|
|
315
|
+
|
|
316
|
+
def _query_csi(
|
|
317
|
+
self,
|
|
318
|
+
path: str,
|
|
319
|
+
zones: list[str],
|
|
320
|
+
entries: list[str],
|
|
321
|
+
subentries: list[str],
|
|
322
|
+
filter: str | None,
|
|
323
|
+
zosmf_auth: tuple[str, ...],
|
|
324
|
+
proxy_auth: tuple[str, ...],
|
|
325
|
+
wait: bool,
|
|
326
|
+
) -> list[CsiEntry] | dict[str, Any]:
|
|
327
|
+
if "*" in entries and len(entries) > 1:
|
|
328
|
+
raise ZosmfSoftwareManagementError("'*' cannot be combined with other entry types.")
|
|
329
|
+
elif "*" in subentries and len(subentries) > 1:
|
|
330
|
+
raise ZosmfSoftwareManagementError(
|
|
331
|
+
"'*' cannot be combined with other subentry types."
|
|
332
|
+
)
|
|
333
|
+
resp = self.http.post(
|
|
334
|
+
path,
|
|
335
|
+
json={
|
|
336
|
+
"zones": zones,
|
|
337
|
+
"entries": entries,
|
|
338
|
+
"subentries": subentries,
|
|
339
|
+
"filter": filter or "",
|
|
340
|
+
},
|
|
341
|
+
)
|
|
342
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementRequestError)
|
|
343
|
+
if wait:
|
|
344
|
+
status = self.get_query_csi_status(resp.json()["statusurl"], wait=True)
|
|
345
|
+
return status
|
|
346
|
+
return resp.json()
|
|
347
|
+
|
|
348
|
+
def query_csi_by_uuid(
|
|
349
|
+
self,
|
|
350
|
+
uuid: str,
|
|
351
|
+
zones: list[str],
|
|
352
|
+
entries: list[str],
|
|
353
|
+
subentries: list[str] = ["*"],
|
|
354
|
+
filter: str | None = None,
|
|
355
|
+
zosmf_auth: tuple[str, ...] = (),
|
|
356
|
+
proxy_auth: tuple[str, ...] = (),
|
|
357
|
+
wait: bool = True,
|
|
358
|
+
) -> list[CsiEntry] | dict[str, Any]:
|
|
359
|
+
"""Query CSI data for a software instance identified by its UUID.
|
|
360
|
+
|
|
361
|
+
Args:
|
|
362
|
+
uuid: UUID of the software instance to query.
|
|
363
|
+
zones: CSI zones to search.
|
|
364
|
+
entries: Entry types to retrieve. ``"*"`` cannot be combined with
|
|
365
|
+
other entry types.
|
|
366
|
+
subentries: Subentry types to retrieve. ``"*"`` cannot be combined
|
|
367
|
+
with other subentry types.
|
|
368
|
+
filter: Optional filter expression sent to z/OSMF.
|
|
369
|
+
zosmf_auth: Reserved compatibility argument; currently not applied.
|
|
370
|
+
proxy_auth: Reserved compatibility argument; currently not applied.
|
|
371
|
+
wait: If true, poll until the query completes and return its entries.
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
A list of ``CsiEntry`` objects when ``wait`` is true; otherwise,
|
|
375
|
+
the initial response dictionary from z/OSMF.
|
|
376
|
+
|
|
377
|
+
Raises:
|
|
378
|
+
ZosmfSoftwareManagementError: If ``"*"`` is combined with
|
|
379
|
+
other entry or subentry types.
|
|
380
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
381
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
382
|
+
unsuccessful HTTP status.
|
|
383
|
+
httpx2.RequestError: If a request fails before an HTTP response is
|
|
384
|
+
received.
|
|
385
|
+
"""
|
|
386
|
+
return self._query_csi(
|
|
387
|
+
f"/zosmf/swmgmt/swi/{uuid}/csiquery",
|
|
388
|
+
zones,
|
|
389
|
+
entries,
|
|
390
|
+
subentries,
|
|
391
|
+
filter,
|
|
392
|
+
zosmf_auth=zosmf_auth,
|
|
393
|
+
proxy_auth=proxy_auth,
|
|
394
|
+
wait=wait,
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
def query_csi_by_name(
|
|
398
|
+
self,
|
|
399
|
+
name: str,
|
|
400
|
+
system: str,
|
|
401
|
+
zones: list[str],
|
|
402
|
+
entries: list[str],
|
|
403
|
+
subentries: list[str] = ["*"],
|
|
404
|
+
filter: str | None = None,
|
|
405
|
+
zosmf_auth: tuple[str, ...] = (),
|
|
406
|
+
proxy_auth: tuple[str, ...] = (),
|
|
407
|
+
wait: bool = True,
|
|
408
|
+
) -> list[CsiEntry] | dict[str, Any]:
|
|
409
|
+
"""Query CSI data for a software instance identified by name and system.
|
|
410
|
+
|
|
411
|
+
Args:
|
|
412
|
+
name: Name of the software instance to query.
|
|
413
|
+
system: System where the software instance is defined.
|
|
414
|
+
zones: CSI zones to search.
|
|
415
|
+
entries: Entry types to retrieve. ``"*"`` cannot be combined with
|
|
416
|
+
other entry types.
|
|
417
|
+
subentries: Subentry types to retrieve. ``"*"`` cannot be combined
|
|
418
|
+
with other subentry types.
|
|
419
|
+
filter: Optional filter expression sent to z/OSMF.
|
|
420
|
+
zosmf_auth: Reserved compatibility argument; currently not applied.
|
|
421
|
+
proxy_auth: Reserved compatibility argument; currently not applied.
|
|
422
|
+
wait: If true, poll until the query completes and return its entries.
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
A list of ``CsiEntry`` objects when ``wait`` is true; otherwise,
|
|
426
|
+
the initial response dictionary from z/OSMF.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
ZosmfSoftwareManagementError: If ``"*"`` is combined with
|
|
430
|
+
other entry or subentry types.
|
|
431
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
432
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
433
|
+
unsuccessful HTTP status.
|
|
434
|
+
httpx2.RequestError: If a request fails before an HTTP response is
|
|
435
|
+
received.
|
|
436
|
+
"""
|
|
437
|
+
return self._query_csi(
|
|
438
|
+
f"/zosmf/swmgmt/swi/{system}/{name}/csiquery",
|
|
439
|
+
zones,
|
|
440
|
+
entries,
|
|
441
|
+
subentries,
|
|
442
|
+
filter,
|
|
443
|
+
zosmf_auth=zosmf_auth,
|
|
444
|
+
proxy_auth=proxy_auth,
|
|
445
|
+
wait=wait,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
def _get_query_csi_status(self, statusurl: str) -> dict[str, Any]:
|
|
449
|
+
resp = self.http.get(statusurl)
|
|
450
|
+
self._raise_for_status(resp, exc_handler=ZosmfSoftwareManagementRequestError)
|
|
451
|
+
return resp.json()
|
|
452
|
+
|
|
453
|
+
def get_query_csi_status(self, statusurl: str, wait: bool = True) -> list[CsiEntry]:
|
|
454
|
+
"""Retrieve the entries for a CSI query, optionally waiting for completion.
|
|
455
|
+
|
|
456
|
+
Args:
|
|
457
|
+
statusurl: Status URL returned by a CSI query submission.
|
|
458
|
+
wait: Poll every two seconds while the status is ``"running"`` when
|
|
459
|
+
true. When false, parse the entries in the first status response.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
Parsed ``CsiEntry`` objects from the final status response, or from
|
|
463
|
+
the initial response when ``wait`` is false.
|
|
464
|
+
|
|
465
|
+
Raises:
|
|
466
|
+
ZosmfAuthError: If z/OSMF returns HTTP 401.
|
|
467
|
+
ZosmfSoftwareManagementRequestError: If z/OSMF returns another
|
|
468
|
+
unsuccessful HTTP status.
|
|
469
|
+
httpx2.RequestError: If a request fails before an HTTP response is
|
|
470
|
+
received.
|
|
471
|
+
"""
|
|
472
|
+
status = self._get_query_csi_status(statusurl)
|
|
473
|
+
if wait:
|
|
474
|
+
while status["status"] == "running":
|
|
475
|
+
time.sleep(2)
|
|
476
|
+
status = self._get_query_csi_status(statusurl)
|
|
477
|
+
return [from_dict(data_class=CsiEntry, data=entry) for entry in status["entries"]]
|