Skip to content

[New Module] zos_replace #2044

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

Open
wants to merge 77 commits into
base: dev
Choose a base branch
from
Open

[New Module] zos_replace #2044

wants to merge 77 commits into from

Conversation

AndreMarcel99
Copy link
Collaborator

@AndreMarcel99 AndreMarcel99 commented Apr 9, 2025

SUMMARY

Develop the module zos_replace to generate outputs as the community base on re python library and add options to the user for replace regular strings.

Fixes #1994

ISSUE TYPE
  • New Module Pull Request
COMPONENT NAME

Module zos_replace with is code flow to open a file on binary mode to avoid any problem with special characters and maintain consistency on the files given by the users.

ADDITIONAL INFORMATION

The test case ds_backup_no_name works locally, but not on the pipeline, work in progress.

Captura de pantalla 2025-05-12 a la(s) 3 24 46 p m
Captura de pantalla 2025-05-12 a la(s) 3 24 59 p m

Copy link
Collaborator

@richp405 richp405 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use some of the test entries as examples in the doc? Just a thought.

Copy link
Collaborator

@fernandofloresg fernandofloresg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested some changes to docs.

- When set to C(true), the module creates a backup file or data set.
- The backup file name will be returned on either success or failure of
module execution such that data can be retrieved.
- Use generation data set (GDS) relative positive name. e.g. I(SOME.CREATION(+1)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add "is allowed." at the end here.

Suggested change
- Use generation data set (GDS) relative positive name. e.g. I(SOME.CREATION(+1)).
- Use generation data set (GDS) relative positive name is allowed. e.g. I(SOME.CREATION(+1)).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But since this is for backup option, which is bool, I think this entry should be in backup_name.

- The location can be a UNIX System Services (USS) file,
PS (sequential data set), member of a PDS or PDSE, PDS, PDSE.
- The USS file must be an absolute pathname.
- Generation data set (GDS) relative name of generation already
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Generation data set (GDS) relative name of generation already
- It is possible to use a generation data set (GDS) relative name of generation already



def resolve_src_name(module, name, results):
"""Function to solve and validate the exist of the dataset or uss file.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Function to solve and validate the exist of the dataset or uss file.
"""Function to resolve and validate the existence of the dataset or uss file.



def replace_text(content, regexp, replace):
"""Function received the test to work on it to find the regexp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Function received the test to work on it to find the regexp
"""Function received the text to work on it to find the regexp

Parameters
----------
content : list
The part or full text to be modified
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The part or full text to be modified
The partial or complete text to be modified.

@AndreMarcel99 AndreMarcel99 requested a review from rexemin May 16, 2025 16:58
@AndreMarcel99
Copy link
Collaborator Author

Captura de pantalla 2025-05-16 a la(s) 11 44 44 a m
Captura de pantalla 2025-05-16 a la(s) 11 44 54 a m

Copy link
Collaborator

@rexemin rexemin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing all comments I've had over the past month, this module looks really good

Copy link
Collaborator

@surendrababuravella surendrababuravella left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine

Copy link
Collaborator

@fernandofloresg fernandofloresg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested few changes, btw can you also add this module name to the github issue templates?

def set_ds_environment(ansible_zos_module, temp_file, ds_name, ds_type, content):
hosts = ansible_zos_module
hosts.all.shell(cmd=f"echo \"{content}\" > {temp_file}")
hosts.all.zos_data_set(name=ds_name, type=ds_type)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use ZOAU utilities with shell module to reduce the module interdependency in tests. This will be useful when migrating to 1.4.0.

Copy link
Collaborator

@fernandofloresg fernandofloresg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Great work on this module, only requested an improvement but this is ready for me. Will see if we can engage a technical writer to review docs content.

@AndreMarcel99
Copy link
Collaborator Author

Screenshot 2025-06-02 at 3 17 39 p m
Screenshot 2025-06-02 at 3 17 49 p m

Copy link
Collaborator

@ddimatos ddimatos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great @AndreMarcel99 , I really like what you have done. All my comments are minor but should be addressed.

- If I(src) is a data set member and backup_name is not provided, the data set
member will be backed up to the same partitioned data set with a randomly generated
member name.
- If it is a Generation Data Set (GDS), use a relative positive name, e.g., I(SOME.CREATION(+1)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is cosmetic bu tif you move this line "If it is a Generation Data Set (GDS), use a relative positive name, e.g., I(SOME.CREATION(+1))." right after the line 48 where you have "If the source is an MVS data set...." then you would be grouping the use case where if it is a certain type, followed then by use cases "it is not provided".

Basically the GDS feels off because its at the bottom after the section "It is not provided"

- If I(src) is a data set member and backup_name is not provided, the data set
member will be backed up to the same partitioned data set with a randomly generated
member name.
- If it is a Generation Data Set (GDS), use a relative positive name, e.g., I(SOME.CREATION(+1)).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For backup_name not provided types USS you cover what happens, you also cover what happens when the backup_name is not provided when the src is a data set member but its not clear to me what happens if the types are either sequential or GDS (as in what happens when not provided for these two types).

requires it to be provided with correct encoding to read the content
of a USS file or data set. If this parameter is not provided, this
module assumes that USS file or data set is encoded in IBM-1047.
- Supported character sets rely on the charset conversion utility (iconv)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will let you decide, but how would one find the list of character sets supported? We do have doc for this because its to large to list in any module, that doc is here:
https://ibm.github.io/z_ansible_collections_doc/ibm_zos_core/docs/source/character_set.html

And it discusses the iconv -l command that will aid in list the supported encodings for iconv.
I believe the encoding module puts this information in the notes section, it does not have to be in the notes section but I leave this up to you.

default: IBM-1047
disable_regex:
description:
- A list or string that allows the user to specify choices "before", "after", or "regexp" as regular strings instead of regex patterns.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit confused by this module option, the example cleared it up some, here are my thoughts but also think more needs to be put into this description, maybe when I get to the code I will have a better understanding.

I suggest don't speak in third person "A list or string that allows the user to specify choices" , instead "A list or string that enables you to..." or just "enables....".

Don't say choices when its not really a choice given its type is raw , find another way have the user use only one of these 3 strings "before", "after", or "regexp", see below at my attempt to convey this.

Since your type is raw, what happens if a user does this "disable_regex:"before, after, regexp", which is probably what you want them to think in terms of choices, likely this is not supported so we might need to be a bit more clear on this.

Here is my attempt with not fully understanding this option, it's a bit confusing because I believe (without having looked at code) what this option is doing is disabling the regular expression processing, for example, you want to match this line but not expand the *, "regexp: //SYSPRINT DD SYSOUT=*"

      - A list or string that disables the regular expression processing for special characters. 
      - This is useful when the I(regex) to match is a string that contains special characters such as `*` that should not be expanded as a regular expression.
      - The supported options are "before", "after", or "regexp" as regular strings.

Copy link
Collaborator

@fernandofloresg fernandofloresg Jun 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ddimatos Multi option in this is supported. Maybe a clearer way to say what this module does when this option is given is that treats the fields as literal instead of regex expressions, that way if you have a complex regex that you don't want to waste time escaping or don't have the skills to do so just disable the regex for those fields and the text searched for in the text "as is".

RETURN = r"""
backup_name:
description: Name of the backup file or data set that was created.
returned: if backup=true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing, returned if backup=true yet in the documentation it states it will "be returned on either success or failure"

      - The backup file name will be returned on either success or failure of
        module execution such that data can be retrieved.

type: int
sample: 5
msg:
description: Error messages from the module
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is msg really used for error messages? I have not read down through the code but does not align to the Ansible doc for a module https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#msg

@AndreMarcel99 AndreMarcel99 requested a review from ddimatos June 4, 2025 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Epic] [zos_replace] Module development
6 participants