Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the dynamically created destination attributes #773

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9306a75
First iteration to get dynamic values
AndreMarcel99 May 8, 2023
46a3d57
Spaces and lines rectified
AndreMarcel99 May 8, 2023
3fb6279
Add validation and extra variable to ensure consistency
AndreMarcel99 May 8, 2023
def73d9
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 May 8, 2023
47e027e
Whitespaces
AndreMarcel99 May 9, 2023
edafe7c
Change imports in test_zos_mount_func
AndreMarcel99 May 9, 2023
98b10c0
Update test_zos_fetch_func imports
AndreMarcel99 May 9, 2023
1b370a2
Update all imports for pipelines runs
AndreMarcel99 May 9, 2023
4781a60
Revert "Update all imports for pipelines runs"
AndreMarcel99 May 9, 2023
37561b0
Update data_set.py imports
AndreMarcel99 May 9, 2023
4c772b4
Revert "Update data_set.py imports"
AndreMarcel99 May 9, 2023
0ca30d2
Update data_set imports
AndreMarcel99 May 9, 2023
46bd7fd
Update data_set imports
AndreMarcel99 May 9, 2023
9e11936
Update data_set imports
AndreMarcel99 May 9, 2023
3bc0a0a
Restore import
AndreMarcel99 May 10, 2023
e833c18
Restore the imports
AndreMarcel99 May 17, 2023
66c2ab7
Add fragment
AndreMarcel99 May 19, 2023
d364f2d
Solve a typo
AndreMarcel99 May 19, 2023
0369b79
Solve z/OS 2.5 HFS
AndreMarcel99 May 22, 2023
e983f34
Solve declaration error
AndreMarcel99 May 22, 2023
7aaa0d8
Solve HFS and solution by now
AndreMarcel99 May 23, 2023
dfe3f1f
Ensure HFS working with HFS
AndreMarcel99 May 23, 2023
4904db3
Better working on HFS testing problems
AndreMarcel99 May 24, 2023
1dc6116
Change to cover many cases and add test
AndreMarcel99 May 27, 2023
6fb43b7
Modified changelog, corrected typos and shortemed file name
fernandofloresg May 27, 2023
7899253
Delete 773-Return-the-dynamically-created-destintation-attributres.yaml
fernandofloresg May 29, 2023
b1d0a04
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
fernandofloresg May 29, 2023
859fe76
Update test_zos_data_set_func.py
fernandofloresg May 29, 2023
7ed387b
Add documentation
AndreMarcel99 May 29, 2023
62938ec
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 May 29, 2023
7f7e59c
Adjust spaces
AndreMarcel99 May 30, 2023
e7d4432
Merge branch 'enhancement/419/Return_the_dynamically_created_destinta…
AndreMarcel99 May 30, 2023
d501119
Solve spaces in documentation
AndreMarcel99 May 30, 2023
d699e48
Solve problems on spaces in documentation
AndreMarcel99 May 30, 2023
a8ddfea
Adjust fragment and add validation for vsams
AndreMarcel99 May 30, 2023
3d21405
Better redaction to documentation
AndreMarcel99 May 30, 2023
c36f62b
Solve spaces
AndreMarcel99 May 31, 2023
9bc0dc1
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 Jun 2, 2023
d40ec82
Change documentation of code and collection
AndreMarcel99 Jun 5, 2023
540e04c
Merge branch 'enhancement/419/Return_the_dynamically_created_destinta…
AndreMarcel99 Jun 5, 2023
93381b3
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 Jun 5, 2023
51b5a18
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 Jun 6, 2023
d1f3581
Change words in documentation
AndreMarcel99 Jun 7, 2023
0196085
Merge branch 'enhancement/419/Return_the_dynamically_created_destinta…
AndreMarcel99 Jun 7, 2023
19ccf1c
Merge branch 'dev' into enhancement/419/Return_the_dynamically_create…
AndreMarcel99 Jun 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
minor_changes:
- zos_copy - Adds block_size, record_format, record_length, space_primary,
space_secondary, space_type and type in the return output when
the destination data set does not exist and has to be created
by the module.
(https://github.com/ansible-collections/ibm_zos_core/pull/773)
7 changes: 6 additions & 1 deletion plugins/action/zos_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ def _update_result(is_binary, copy_res, original_args):
src = copy_res.get("src")
note = copy_res.get("note")
backup_name = copy_res.get("backup_name")
dest_data_set_attrs = copy_res.get("dest_data_set_attrs")
updated_result = dict(
dest=copy_res.get("dest"),
is_binary=is_binary,
Expand All @@ -356,7 +357,6 @@ def _update_result(is_binary, copy_res, original_args):
updated_result["note"] = note
if backup_name:
updated_result["backup_name"] = backup_name

if ds_type == "USS":
updated_result.update(
dict(
Expand All @@ -372,6 +372,11 @@ def _update_result(is_binary, copy_res, original_args):
checksum = copy_res.get("checksum")
if checksum:
updated_result["checksum"] = checksum
if dest_data_set_attrs is not None:
if len(dest_data_set_attrs) > 0:
dest_data_set_attrs.pop("name")
updated_result["dest_created"] = True
updated_result["destination_attributes"] = dest_data_set_attrs

return updated_result

Expand Down
109 changes: 105 additions & 4 deletions plugins/modules/zos_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,61 @@
returned: success
type: str
sample: SAMPLE.SEQ.DATA.SET
dest_created:
description: Indicates whether the module created the destination.
returned: success and if dest was created by the module.
type: bool
sample: true
destination_attributes:
description: Attributes of a dest created by the module.
returned: success and destination was created by the module.
type: dict
contains:
block_size:
description:
Block size of the dataset.
type: int
sample: 32760
record_format:
description:
Record format of the dataset.
type: str
sample: FB
record_length:
description:
Record length of the dataset.
type: int
sample: 45
space_primary:
rexemin marked this conversation as resolved.
Show resolved Hide resolved
description:
Allocated primary space for the dataset.
type: int
sample: 2
space_secondary:
description:
Allocated secondary space for the dataset.
type: int
sample: 1
space_type:
description:
Unit of measurement for space.
type: str
sample: K
type:
description:
Type of dataset allocated.
type: str
sample: PDSE
sample:
{
"block_size": 32760,
"record_format": "FB",
"record_length": 45,
"space_primary": 2,
"space_secondary": 1,
"space_type": "K",
"type": "PDSE"
}
checksum:
description: SHA256 checksum of the file after running zos_copy.
returned: C(validate) is C(true) and if dest is USS
Expand Down Expand Up @@ -1977,6 +2032,45 @@ def is_member_wildcard(src):
)


def get_attributes_of_any_dataset_created(
dest,
src_ds_type,
src,
src_name,
is_binary,
volume=None
):
"""
Get the attributes of dataset created by the function allocate_destination_data_set
except for VSAM.

Arguments:
dest (str) -- Name of the destination data set.
src_ds_type (str) -- Source of the destination data set.
src (str) -- Name of the source data set, used as a model when appropiate.
src_name (str) -- Extraction of the source name without the member pattern.
is_binary (bool) -- Whether the data set will contain binary data.
volume (str, optional) -- Volume where the data set should be allocated into.

Returns:
params (dict) -- Parameters used for the dataset created as name, type,
space_primary, space_secondary, record_format, record_length, block_size and space_type
"""
params = {}
if src_ds_type == "USS":
if os.path.isfile(src):
size = os.stat(src).st_size
params = get_data_set_attributes(dest, size=size, is_binary=is_binary, volume=volume)
else:
size = os.path.getsize(src)
params = get_data_set_attributes(dest, size=size, is_binary=is_binary, volume=volume)
else:
src_attributes = datasets.listing(src_name)[0]
size = int(src_attributes.total_space)
params = get_data_set_attributes(dest, size=size, is_binary=is_binary, volume=volume)
return params


def allocate_destination_data_set(
src,
dest,
Expand Down Expand Up @@ -2006,6 +2100,9 @@ def allocate_destination_data_set(

Returns:
bool -- True if the data set was created, False otherwise.
dest_params (dict) -- Parameters used for the dataset created as name,
block_size, record_format, record_length, space_primary, space_secondary,
space_type, type.
"""
src_name = data_set.extract_dsname(src)
is_dest_empty = data_set.DataSet.is_empty(dest) if dest_exists else True
Expand All @@ -2014,8 +2111,11 @@ def allocate_destination_data_set(
# empty dataset was created for the user by an admin/operator, and they don't have permissions
# to create new datasets.
# These rules assume that source and destination types are compatible.
# Create the dict that will contains the values created by the module if it's empty action module will
# not display the content.
dest_params = {}
if dest_exists and is_dest_empty:
return False
return False, dest_params

# Giving more priority to the parameters given by the user.
if dest_data_set:
Expand Down Expand Up @@ -2086,8 +2186,9 @@ def allocate_destination_data_set(
volumes = [volume] if volume else None
data_set.DataSet.ensure_absent(dest, volumes=volumes)
data_set.DataSet.allocate_model_data_set(ds_name=dest, model=src_name, vol=volume)

return True
if dest_ds_type not in data_set.DataSet.MVS_VSAM:
dest_params = get_attributes_of_any_dataset_created(dest, src_ds_type, src, src_name, is_binary, volume)
return True, dest_params


def normalize_line_endings(src, encoding=None):
Expand Down Expand Up @@ -2449,7 +2550,7 @@ def run_module(module, arg_def):

try:
if not is_uss:
res_args["changed"] = allocate_destination_data_set(
res_args["changed"], res_args["dest_data_set_attrs"] = allocate_destination_data_set(
temp_path or src,
dest_name, src_ds_type,
dest_ds_type,
Expand Down
7 changes: 7 additions & 0 deletions tests/functional/modules/test_zos_copy_func.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,7 @@ def test_copy_file_to_non_existing_sequential_data_set(ansible_zos_module, src):
assert cp_res.get("msg") is None
assert cp_res.get("changed") is True
assert cp_res.get("dest") == dest
assert cp_res.get("dest_created") is True
assert cp_res.get("is_binary") == src["is_binary"]
for v_cp in verify_copy.contacted.values():
assert v_cp.get("rc") == 0
Expand Down Expand Up @@ -1467,6 +1468,7 @@ def test_copy_ps_to_non_existing_ps(ansible_zos_module):
assert result.get("msg") is None
assert result.get("changed") is True
assert result.get("dest") == dest
assert result.get("dest_created") is True
for result in verify_copy.contacted.values():
assert result.get("rc") == 0
assert result.get("stdout") != ""
Expand Down Expand Up @@ -1816,6 +1818,7 @@ def test_copy_file_to_non_existing_pdse(ansible_zos_module, is_remote):
assert cp_res.get("msg") is None
assert cp_res.get("changed") is True
assert cp_res.get("dest") == dest_path
assert cp_res.get("dest_created") is True
for v_cp in verify_copy.contacted.values():
assert v_cp.get("rc") == 0
finally:
Expand Down Expand Up @@ -1844,6 +1847,7 @@ def test_copy_dir_to_non_existing_pdse(ansible_zos_module):
assert result.get("msg") is None
assert result.get("changed") is True
assert result.get("dest") == dest
assert result.get("dest_created") is True
for result in verify_copy.contacted.values():
assert result.get("rc") == 0
finally:
Expand Down Expand Up @@ -1875,6 +1879,7 @@ def test_copy_dir_crlf_endings_to_non_existing_pdse(ansible_zos_module):
assert result.get("msg") is None
assert result.get("changed") is True
assert result.get("dest") == dest
assert result.get("dest_created") is True
for result in verify_copy.contacted.values():
assert result.get("rc") == 0
assert len(result.get("stdout_lines")) == 2
Expand Down Expand Up @@ -1954,6 +1959,7 @@ def test_copy_data_set_to_non_existing_pdse(ansible_zos_module, src_type):
assert cp_res.get("msg") is None
assert cp_res.get("changed") is True
assert cp_res.get("dest") == dest
assert cp_res.get("dest_created") is True
for v_cp in verify_copy.contacted.values():
assert v_cp.get("rc") == 0
assert v_cp.get("stdout") != ""
Expand Down Expand Up @@ -2415,6 +2421,7 @@ def test_copy_member_to_non_existing_seq_data_set(ansible_zos_module, src_type):
assert result.get("msg") is None
assert result.get("changed") is True
assert result.get("dest") == dest
assert result.get("dest_created") is True
for result in verify_copy.contacted.values():
assert result.get("rc") == 0
assert result.get("stdout") != ""
Expand Down