Creating a Python building block
You can extend the Wazi Deploy Python translator that runs the Python building blocks. You can create your own Python building blocks and call them from the deployment method to implement your own action steps.
This scenario is the continuation of the Static deployment with the Python translator scenario.
For example, you might want to implement a new action after the copy to the target PDS. This action submits the JCL that was deployed from the package. Implementing a new action consists in providing a new Python building block that complies with the Wazi Deploy API.
- Create a folder and name it
modulesfor example. - In this folder, create a
my_job_submit.pyPython building block with the following contents:from wazideploy_translator.service.evidences import EvidenceStatus from wazideploy_translator.service.python_module import PythonModule import re class JobSubmit (PythonModule): """ JobSubmit module for use to trigger a JCL in the scope of the deployment. Its extend the base PythonModule class. """ def __init__(self): super().__init__() def process(self, deployment_plan:dict, activity:dict, action:dict, step:dict, environment:dict, working_folder:str, extra_vars:dict, dry_run:bool, verbose:bool, evidences:dict, **kwargs): """ Submit the jobs listed in the current step. Returns ======= list[status, status message, evidences collected] Parameters ========== `deployment_plan` : dict The Full Deployment Plan `activity` : dict The current activity in the Deployment Plan `action` : dict The current action in the Deployment Plan `step` : dict The current step in the Deployment Plan `environment` : dict The environment configuration (--envFile option of wazideploy-deploy) `working_folder` : str The current working folder (--workingFolder option of wazideploy-deploy) `extra_vars` : dict The extra environment variables (--extraVars option of wazideploy-deploy) `evidences` : dict The evidences at the beginning of the execution of the building block. This dictionary is a readonly dictionary. Other Parameters ================ `dry_run` : bool Dry Run (must not modify the target) `verbose` : bool Enable verbose messages. """ super().process(deployment_plan, activity, action, step, environment, working_folder, extra_vars, dry_run, verbose, evidences) step_success= True if not dry_run: step_msg = 'All items completed' else: step_msg = 'Dry run' step_results = [] # Browse all artifacts for artifact in step['artifacts']: if not dry_run: # Apply to all applicable types path = PythonModule.get_artifact_path(artifact) if path is None: continue var_type = PythonModule.get_property(step, 'var_type') if not var_type: var_type = 'types' artifact_items_types = environment.get(var_type, []) for item_type in artifact_items_types: if re.match(item_type['pattern'], path, re.IGNORECASE): job_failed, job, job_result = self.submit_job ( f"{item_type['dataset']}({artifact['name']})", max_rc=0, verbose=False) if job_failed : print(f"*? ERROR: Job {job.id} failed") job_status = EvidenceStatus.FAILED.value step_success = False job_msg = f"Job {job.id} failed" step_msg = "Job failed" else: job_status = EvidenceStatus.OK.value job_msg = f"Job {job.id} succeeded" result = {"status": job_status, "msg": job_msg, "results": job_result} step_results.append(result) return[step_success, step_msg, step_results] - At the end of the static-deployment-method.yml deployment method, add the
following activity to submit the JCL that was deployed from the
package:
- name: "Job Submit Activity" description: | This activity will submit JOBs in the package actions: - name: "Job Submit Action" states: - UNDEFINED steps: - name: "Job Submit Action" properties: - key: template value: my_job_submit types: - name: 'jcl' is_artifact: True - Provide a new .tar file named package.v3.tar. This
file must contain a JCL with the .jcl extension.In order for the JCL to be correctly processed, add the new JCL type definition in the Python environment variables file (zos-environment.yml).
- Enter the common characteristics for this new type as
follows:
ommon_pds_txt_spec: type: LIBRARY primary_space: 10CYL secondary_space: 20CYL record_format: FB record_length: 80 - Create a types variable. Under this types variable, enter
the jcl
pattern as follows:
types: - pattern: .*.JCL$ dataset: "{{ hlq }}.JCL" dataset_backup: "{{ hlq }}.BACK.JCL" spec: "{{ common_pds_txt_spec }}" #encoding: # from: UTF-8 # to: IBM-1047
- Enter the common characteristics for this new type as
follows:
- Generate the deployment plan with the following
command:
wazideploy-generate -dm static-deployment-method.yml -dp deployment_plan.yml -pif package.v3.tar - Trigger the deployment of the last version of the package.To do so, enter the following commands. The first command (
export DEPLOY_MODULES_PATH) is used to specify the location where the external actions (Python building blocks) of thewazideploy-deploycommand are defined. It is a list of folders separated by colons (:) where your building blocks reside.export DEPLOY_MODULES_PATH=$PWD/moduleswazideploy-deploy -dp deployment_plan.yml -pif package.v3.tar -ef zos-environment.yml -wf ./work
At this stage, the JCL should be deployed and automatically submitted.
The job log should be collected in the evidence
file that was produced by the wazideploy-deploy command. You can see where
the evidence file is stored in the output console of the wazideploy-deploy
command.
Wazi Deploy Python API
Python modules
The Python modules provide utility functions to create building blocks.
- PythonModule.get_property(entity: dict, property_key: str)
- Description
- This method gets the properties key that is associated with the entity in
the deployment plan. An entity can be one of the following elements:
- An activity
- An action
- A step
- An artifact
- Returns
- The value of the properties key
- Return type
-
- str
- Parameters
-
- entity (
dict): The current entity, which isactivity,action,step, orartifactin the deployment plan - property_key (
str): The properties key of the entity in the deployment plan
- entity (
- PythonModule.get_artifact_type(artifact: dict)
- Description
- This method gets the value of the type key in the properties of the artifact in the deployment plan. This type is indicated in the deployment method.
- Returns
- The value of the artifact type
- Return type
-
- str
- Parameters
-
- artifact (
dict): The artifact
- artifact (
- PythonModule.get_artifact_path(artifact: dict)
- Description
- This method gets the value of the path key in the properties of the artifact in the deployment plan. It is the path to the artifact in the package file.
- Returns
- The value of the artifact path
- Return type
-
- str
- Parameters
-
- artifact (
dict): The artifact
- artifact (
- PythonModule.render_jinja2_template(template_file:str, output_file: str, environment:dict,
extra_vars:dict, verbose:bool = True, **kwargs)
- Description
- This method transforms a Jinja2 template into a file where the variables are resolved.
- Returns
- None
- Return type
- None
- Parameters
-
- template_file (
str): The source Jinja2 file. - output_file (
str): The output file where the variables are resolved. - environment (
dict): The z/OS environment configuration file that is used by the Wazi Deploy Python deployment command (wazideploy-deploy). - extra_vars (
dict): The value of the variables that were added to the environment variables file as extra_vars. These variables can be indicated in the Wazi Deploy Python deployment command (wazideploy-deploy). - verbose (
bool)
- template_file (
- PythonModule.submit_job(job_source:str, max_rc:int = -1, wait_time_s:int = -1,
verbose:bool = True, **kwargs)
- Description
- This method submits a z/OS job.
- Returns
(job_status(str), job (ZOAU job), job_result (array))
- Return type
- Tuple
- Parameters
-
- job_source (
str): The job location (z/OS UNIX System Services or dataset) - max_rc (
int): The maximum return code of the JCL execution - wait_time_s (
int): The maximum time in seconds to wait for the job to complete - verbose (
bool)
- job_source (