Skip to content

Commit b3146ff

Browse files
[2.0][zos_data_set] Added new return values for zos_data_set (#2206)
* Added return values * Added changelog * Updated changelogsg * Updated so that we get attribtues from zoau data set creation * Fixed certain failure cases * Added attributes return when creating a data set * Modified dependent files * Updated data set member * Commented test case in zos_backup_restore * Fixed sanity issues * Fixed sanity issues * Updated tests * Update 2206-zos_data_set-interface-update.yml
1 parent bd1ee0e commit b3146ff

File tree

8 files changed

+298
-61
lines changed

8 files changed

+298
-61
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
minor_changes:
2+
- zos_data_set - Adds return value ``data_sets`` which contains the attributes of all data sets created.
3+
(https://github.com/ansible-collections/ibm_zos_core/pull/2206)

plugins/module_utils/data_set.py

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ def ensure_present(
204204
arguments.pop("replace", None)
205205
present = False
206206
changed = False
207+
data_set = None
207208
if DataSet.data_set_cataloged(name, tmphlq=tmp_hlq):
208209
present = True
209210
# Validate volume conflicts when:
@@ -222,7 +223,7 @@ def ensure_present(
222223

223224
if not present:
224225
try:
225-
DataSet.create(**arguments)
226+
changed, data_set = DataSet.create(**arguments)
226227
except DatasetCreateError as e:
227228
raise_error = True
228229
# data set exists on volume
@@ -236,11 +237,11 @@ def ensure_present(
236237
raise
237238
if present:
238239
if not replace:
239-
return changed
240-
DataSet.replace(**arguments)
240+
return changed, data_set
241+
changed, data_set = DataSet.replace(**arguments)
241242
if type.upper() == "ZFS":
242243
DataSet.format_zfs(name)
243-
return True
244+
return changed, data_set
244245

245246
@staticmethod
246247
def ensure_absent(name, volumes=None, tmphlq=None, noscratch=False):
@@ -1249,7 +1250,8 @@ def replace(
12491250
"""
12501251
arguments = locals()
12511252
DataSet.delete(name)
1252-
DataSet.create(**arguments)
1253+
changed, data_set = DataSet.create(**arguments)
1254+
return changed, data_set
12531255

12541256
@staticmethod
12551257
def _build_zoau_args(**kwargs):
@@ -1417,7 +1419,7 @@ def create(
14171419
msg="Unable to verify the data set was created. Received DatasetVerificationError from ZOAU.",
14181420
)
14191421
changed = data_set is not None
1420-
return changed
1422+
return changed, data_set
14211423

14221424
@staticmethod
14231425
def delete(name, noscratch=False):
@@ -2723,7 +2725,9 @@ def ensure_present(self, tmp_hlq=None, replace=False, force=False):
27232725
"tmp_hlq": tmp_hlq,
27242726
"force": force,
27252727
}
2726-
rc = DataSet.ensure_present(**arguments)
2728+
rc, data_set = DataSet.ensure_present(**arguments)
2729+
if data_set is not None:
2730+
self.merge_attributes_from_zoau_data_set(data_set)
27272731
self.set_state("present")
27282732
return rc
27292733

@@ -2843,6 +2847,37 @@ def set_state(self, new_state):
28432847
raise ValueError(f"State {self.state} not supported for MVSDataset class.")
28442848
return True
28452849

2850+
def merge_attributes_from_zoau_data_set(self, zoau_data_set):
2851+
# print(zoau_data_set)
2852+
self.name = zoau_data_set.name
2853+
self.record_format = zoau_data_set.record_format and zoau_data_set.record_format.lower()
2854+
self.record_length = zoau_data_set.record_length
2855+
self.volumes = zoau_data_set.volume and zoau_data_set.volume.lower()
2856+
self.block_size = zoau_data_set.block_size
2857+
self.type = zoau_data_set.type and zoau_data_set.type.lower()
2858+
2859+
@property
2860+
def attributes(self):
2861+
data_set_attributes = {
2862+
"name": self.name,
2863+
"state": self.state,
2864+
"type": self.data_set_type,
2865+
"space_primary": self.space_primary,
2866+
"space_secondary": self.space_secondary,
2867+
"space_type": self.space_type,
2868+
"record_format": self.record_format,
2869+
"sms_storage_class": self.sms_storage_class,
2870+
"sms_data_class": self.sms_data_class,
2871+
"sms_management_class": self.sms_management_class,
2872+
"record_length": self.record_length,
2873+
"block_size": self.block_size,
2874+
"directory_blocks": self.directory_blocks,
2875+
"key_offset": self.key_offset,
2876+
"key_length": self.key_length,
2877+
"volumes": self.volumes,
2878+
}
2879+
return data_set_attributes
2880+
28462881

28472882
class Member():
28482883
"""Represents a member on z/OS.
@@ -2899,6 +2934,15 @@ def ensure_present(self, replace=None, tmphlq=None):
28992934
rc = DataSet.ensure_member_present(self.name, replace, tmphlq=tmphlq)
29002935
return rc
29012936

2937+
@property
2938+
def attributes(self):
2939+
member_attributes = {
2940+
"name": self.name,
2941+
"parent_data_set_type": self.parent_data_set_type,
2942+
"data_set_type": self.data_set_type,
2943+
}
2944+
return member_attributes
2945+
29022946

29032947
class GenerationDataGroup():
29042948
"""Represents a Generation Data Group base in z/OS.
@@ -2947,8 +2991,7 @@ def __init__(
29472991
self.data_set_type = "gdg"
29482992
self.raw_name = name
29492993
self.gdg = None
2950-
# Removed escaping since is not needed by the GDG python api.
2951-
# self.name = DataSet.escape_data_set_name(self.name)
2994+
self.state = 'present'
29522995

29532996
@staticmethod
29542997
def _validate_gdg_name(name):
@@ -2977,6 +3020,7 @@ def create(self):
29773020
fifo=self.fifo,
29783021
)
29793022
self.gdg = gdg
3023+
self.state = 'present'
29803024
return True
29813025

29823026
def ensure_present(self, replace):
@@ -3097,6 +3141,21 @@ def clear(self):
30973141
gdg_view.clear()
30983142
return True
30993143

3144+
@property
3145+
def attributes(self):
3146+
data_set_attributes = {
3147+
"name": self.name,
3148+
"state": self.state,
3149+
"type": self.data_set_type,
3150+
"empty": self.empty,
3151+
"extended": self.extended,
3152+
"fifo": self.fifo,
3153+
"limit": self.limit,
3154+
"purge": self.purge,
3155+
"scratch": self.scratch,
3156+
}
3157+
return data_set_attributes
3158+
31003159

31013160
def is_member(data_set):
31023161
"""Determine whether the input string specifies a data set member.

plugins/modules/zos_archive.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ def _create_dest_data_set(
13281328
if space_type is None:
13291329
arguments.update(space_type="m")
13301330
arguments.pop("self")
1331-
changed = data_set.DataSet.ensure_present(**arguments)
1331+
changed, zoau_data_set = data_set.DataSet.ensure_present(**arguments)
13321332
return arguments["name"], changed
13331333

13341334
def create_dest_ds(self, name):

plugins/modules/zos_data_set.py

Lines changed: 171 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -825,11 +825,127 @@
825825
- "222222"
826826
"""
827827
RETURN = r"""
828-
names:
829-
description: The data set names, including temporary generated data set names, in the order provided to the module.
828+
data_sets:
829+
description: The affected data set, including temporary generated data set, in the order provided to the module.
830830
returned: always
831831
type: list
832832
elements: str
833+
contains:
834+
name:
835+
description: The data set name.
836+
type: str
837+
returned: always
838+
state:
839+
description: The final state desired for specified data set.
840+
type: str
841+
returned: always
842+
type:
843+
description: The data set type.
844+
type: str
845+
returned: always
846+
space_primary:
847+
description: The amount of primary space allocated for the dataset.
848+
type: int
849+
returned: always
850+
space_secondary:
851+
description: The amount of secondary space allocated for the dataset.
852+
type: int
853+
returned: always
854+
space_type:
855+
description: The unit of measurement used when defining primary and secondary space.
856+
type: str
857+
returned: always
858+
record_format:
859+
description: The format of the data set.
860+
type: str
861+
sample: fb
862+
returned: always
863+
sms_storage_class:
864+
description:
865+
- The storage class for the SMS-managed dataset.
866+
- Returned empty if the data set was not specified as SMS-managed dataset.
867+
type: str
868+
returned: always
869+
sms_data_class:
870+
description:
871+
- The data class for an SMS-managed dataset.
872+
- Returned empty if the data set was not specified as SMS-managed dataset.
873+
type: str
874+
returned: always
875+
sms_management_class:
876+
description:
877+
- The management class for an SMS-managed dataset.
878+
- Returned empty if the data set was not specified as SMS-managed dataset.
879+
type: str
880+
returned: always
881+
record_length:
882+
description: The length, in bytes, of each record in the data set.
883+
type: int
884+
returned: always
885+
block_size:
886+
description: The block size used for the data set.
887+
type: int
888+
returned: always
889+
directory_blocks:
890+
description:
891+
- The number of directory blocks to allocate to the data set.
892+
type: int
893+
returned: always
894+
key_offset:
895+
description: The key offset used when creating a KSDS data set.
896+
type: int
897+
returned: always
898+
key_length:
899+
description: The key length used when creating a KSDS data set.
900+
type: int
901+
returned: always
902+
empty:
903+
description:
904+
- I(empty) attribute for Generation Data Groups.
905+
- Returned empty if the data set provided was not defined as a GDG.
906+
type: bool
907+
returned: always
908+
extended:
909+
description:
910+
- I(extended) attribute for Generation Data Groups.
911+
- Returned empty if the data set provided was not defined as a GDG.
912+
type: bool
913+
returned: always
914+
fifo:
915+
description:
916+
- I(fifo) attribute for Generation Data Groups.
917+
- Returned empty if the data set provided was not defined as a GDG.
918+
type: bool
919+
returned: always
920+
limit:
921+
description:
922+
- I(limit) attribute for Generation Data Groups.
923+
- Returned empty if the data set provided was not defined as a GDG.
924+
type: int
925+
returned: always
926+
purge:
927+
description:
928+
- I(purge) attribute for Generation Data Groups.
929+
- Returned empty if the data set provided was not defined as a GDG.
930+
type: bool
931+
returned: always
932+
scratch:
933+
description:
934+
- I(scratch) attribute for Generation Data Groups.
935+
- Returned empty if the data set provided was not defined as a GDG.
936+
type: bool
937+
returned: always
938+
volumes:
939+
description:
940+
- Specifies the name of the volume(s) where the data set is located.
941+
- Returned empty if volume was not provided.
942+
type: list
943+
returned: always
944+
msg:
945+
description: A string with a generic message relayed to the user.
946+
returned: always
947+
type: str
948+
sample: Error while gathering data set information
833949
"""
834950

835951
from ansible_collections.ibm.ibm_zos_core.plugins.module_utils.better_arg_parser import (
@@ -1737,6 +1853,53 @@ def parse_and_validate_args(params):
17371853
return parsed_args
17381854

17391855

1856+
def build_return_schema(data_set_list):
1857+
""" Builds return values schema with empty values.
1858+
1859+
Parameters
1860+
----------
1861+
data_set_list : dict
1862+
List of data sets.
1863+
1864+
Returns
1865+
-------
1866+
dict
1867+
Dictionary used to return values at execution finalization.
1868+
"""
1869+
data_set_schema = {
1870+
"name": "",
1871+
"state": "",
1872+
"type": "",
1873+
"space_primary": "",
1874+
"space_secondary": "",
1875+
"space_type": "",
1876+
"record_format": "",
1877+
"sms_storage_class": "",
1878+
"sms_data_class": "",
1879+
"sms_management_class": "",
1880+
"record_length": "",
1881+
"block_size": "",
1882+
"directory_blocks": "",
1883+
"key_offset": "",
1884+
"key_length": "",
1885+
"empty": "",
1886+
"extended": "",
1887+
"fifo": "",
1888+
"limit": "",
1889+
"purge": "",
1890+
"scratch": "",
1891+
"volumes": [],
1892+
}
1893+
1894+
data_sets = [data_set_schema.copy() | data_set.attributes for data_set in data_set_list]
1895+
result = {
1896+
"data_sets": data_sets,
1897+
"msg": "",
1898+
"failed": False
1899+
}
1900+
return result
1901+
1902+
17401903
def run_module():
17411904
"""Runs the module.
17421905
@@ -1913,7 +2076,7 @@ def run_module():
19132076
default=False
19142077
),
19152078
)
1916-
result = dict(changed=False, message="", names=[])
2079+
result = dict(changed=False, message="")
19172080

19182081
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
19192082

@@ -1948,6 +2111,8 @@ def run_module():
19482111
if module.params.get("record_format") is not None:
19492112
del module.params["record_format"]
19502113

2114+
data_set_list = []
2115+
19512116
if not module.check_mode:
19522117
try:
19532118
# Update the dictionary for use by better arg parser by adding the
@@ -1956,7 +2121,6 @@ def run_module():
19562121
module_args['state']['dependencies'] = ['batch']
19572122
params = parse_and_validate_args(module.params)
19582123
data_set_param_list = get_individual_data_set_parameters(params)
1959-
result["names"] = [d.get("name", "") for d in data_set_param_list]
19602124

19612125
for data_set_params in data_set_param_list:
19622126
# this returns MVSDataSet, Member or GenerationDataGroup
@@ -1969,11 +2133,12 @@ def run_module():
19692133
force=data_set_params.get("force"),
19702134
noscratch=data_set_params.get("noscratch"),
19712135
)
2136+
data_set_list.append(data_set)
19722137
result["changed"] = result["changed"] or current_changed
2138+
# Build return schema from created data sets.
2139+
result.update(build_return_schema(data_set_list))
19732140
except Exception as e:
19742141
module.fail_json(msg=repr(e), **result)
1975-
if module.params.get("replace"):
1976-
result["changed"] = True
19772142
module.exit_json(**result)
19782143

19792144

0 commit comments

Comments
 (0)