コード例 #1
0
ファイル: zos_copy.py プロジェクト: fabiocosta0305/mtm2021
 def _dest_exists(self, src, dest, task_vars):
     """Determine if destination exists on remote z/OS system"""
     if "/" in dest:
         rc, out, err = self._connection.exec_command(
             "ls -l {0}".format(dest))
         if rc != 0:
             return False
         if len(to_text(out).split("\n")) == 2:
             return True
         if "/" in src:
             src = src.rstrip("/") if src.endswith("/") else src
             dest += "/" + os.path.basename(src)
         else:
             dest += "/" + extract_member_name(src) if is_member(
                 src) else src
         rc, out, err = self._connection.exec_command(
             "ls -l {0}".format(dest))
         if rc != 0:
             return False
     else:
         cmd = "LISTDS '{0}'".format(dest)
         tso_cmd = self._execute_module(
             module_name="ibm.ibm_zos_core.zos_tso_command",
             module_args=dict(commands=[cmd]),
             task_vars=task_vars,
         ).get("output")[0]
         if tso_cmd.get("rc") != 0:
             for line in tso_cmd.get("content"):
                 if "NOT IN CATALOG" in line:
                     return False
     return True
コード例 #2
0
ファイル: zos_copy.py プロジェクト: fabiocosta0305/mtm2021
 def _remote_cleanup(self, dest, dest_exists, task_vars):
     """Remove all files or data sets pointed to by 'dest' on the remote
     z/OS system. The idea behind this cleanup step is that if, for some
     reason, the module fails after copying the data, we want to return the
     remote system to its original state. Which means deleting any newly
     created files or data sets.
     """
     if dest_exists is False:
         if "/" in dest:
             self._connection.exec_command("rm -rf {0}".format(dest))
         else:
             module_args = dict(name=dest, state="absent")
             if is_member(dest):
                 module_args["type"] = "MEMBER"
             self._execute_module(
                 module_name="ibm.ibm_zos_core.zos_data_set",
                 module_args=module_args,
                 task_vars=task_vars,
             )
コード例 #3
0
ファイル: backup.py プロジェクト: feynmanliang/ibm_zos_core
def mvs_file_backup(dsn, bk_dsn=None):
    """Create a backup data set for an MVS data set

    Arguments:
        dsn {str} -- The name of the data set to backup.
                        It could be an MVS PS/PDS/PDSE/VSAM(KSDS), etc.
        bk_dsn {str} -- The name of the backup data set.

    Raises:
        BackupError: When backup data set exists.
        BackupError: When creation of backup data set fails.
    """
    dsn = _validate_data_set_name(dsn).upper()
    if is_member(dsn):
        if not bk_dsn:
            bk_dsn = extract_dsname(dsn) + "({0})".format(temp_member_name())
        bk_dsn = _validate_data_set_name(bk_dsn).upper()
        response = datasets._copy(dsn, bk_dsn)
        if response.rc != 0:
            raise BackupError("Unable to backup {0} to {1}".format(
                dsn, bk_dsn),
                              rc=response.rc,
                              stdout=response.stdout_response,
                              stderr=response.stderr_response)
    else:
        if not bk_dsn:
            bk_dsn = datasets.tmp_name(datasets.hlq())
        bk_dsn = _validate_data_set_name(bk_dsn).upper()
        cp_rc = _copy_ds(dsn, bk_dsn)
        if cp_rc == 12:  # The data set is probably a PDS or PDSE
            # Delete allocated backup that was created when attempting to use _copy_ds()
            # Safe to delete because _copy_ds() would have raised an exception if it did
            # not successfully create the backup data set, so no risk of it predating module invocation
            datasets.delete(bk_dsn)
            _allocate_model(bk_dsn, dsn)
            rc, out, err = _copy_pds(dsn, bk_dsn)
            if rc != 0:
                raise BackupError(
                    "Unable to backup data set {0} to {1}".format(dsn, bk_dsn))
    return bk_dsn
コード例 #4
0
ファイル: zos_copy.py プロジェクト: fabiocosta0305/mtm2021
    def run(self, tmp=None, task_vars=None):
        """ handler for file transfer operations """
        if task_vars is None:
            task_vars = dict()

        result = super(ActionModule, self).run(tmp, task_vars)
        task_args = self._task.args.copy()
        del tmp

        src = task_args.get('src', None)
        b_src = to_bytes(src, errors='surrogate_or_strict')
        dest = task_args.get('dest', None)
        content = task_args.get('content', None)

        # If self._play_context.port is None, that implies the default port 22
        # was used to connect to the remote host.
        sftp_port = task_args.get('sftp_port', self._play_context.port or 22)
        force = _process_boolean(task_args.get('force'), default=True)
        backup = _process_boolean(task_args.get('backup'), default=False)
        local_follow = _process_boolean(task_args.get('local_follow'),
                                        default=False)
        remote_src = _process_boolean(task_args.get('remote_src'),
                                      default=False)
        is_binary = _process_boolean(task_args.get('is_binary'), default=False)
        ignore_sftp_stderr = _process_boolean(
            task_args.get("ignore_sftp_stderr"), default=False)
        backup_name = task_args.get("backup_name", None)
        encoding = task_args.get("encoding", None)
        mode = task_args.get("mode", None)
        owner = task_args.get("owner", None)
        group = task_args.get("group", None)

        is_pds = is_src_dir = False
        temp_path = is_uss = is_mvs_dest = copy_member = src_member = None

        if dest:
            if not isinstance(dest, string_types):
                msg = "Invalid type supplied for 'dest' option, it must be a string"
                return self._exit_action(result, msg, failed=True)
            else:
                is_uss = "/" in dest
                is_mvs_dest = is_data_set(dest)
                copy_member = is_member(dest)
        else:
            msg = "Destination is required"
            return self._exit_action(result, msg, failed=True)

        if src:
            if content:
                msg = "Either 'src' or 'content' can be provided; not both."
                return self._exit_action(result, msg, failed=True)

            elif not isinstance(src, string_types):
                msg = "Invalid type supplied for 'src' option, it must be a string"
                return self._exit_action(result, msg, failed=True)

            elif len(src) < 1 or len(dest) < 1:
                msg = "'src' or 'dest' must not be empty"
                return self._exit_action(result, msg, failed=True)
            else:
                src_member = is_member(src)
                if not remote_src:
                    src = os.path.realpath(src)
                    is_src_dir = os.path.isdir(src)
                    is_pds = is_src_dir and is_mvs_dest

        if not src and not content:
            msg = "'src' or 'content' is required"
            return self._exit_action(result, msg, failed=True)

        if encoding and is_binary:
            msg = "The 'encoding' parameter is not valid for binary transfer"
            return self._exit_action(result, msg, failed=True)

        if (not backup) and backup_name is not None:
            msg = "Backup file provided but 'backup' parameter is False"
            return self._exit_action(result, msg, failed=True)

        if not is_uss:
            if mode or owner or group:
                msg = "Cannot specify 'mode', 'owner' or 'group' for MVS destination"
                return self._exit_action(result, msg, failed=True)

        if not isinstance(sftp_port, int) or not 0 < sftp_port <= 65535:
            msg = "Invalid port provided for SFTP. Expected an integer between 0 to 65535."
            return self._exit_action(result, msg, failed=True)

        if (not force) and self._dest_exists(src, dest, task_vars):
            return self._exit_action(
                result, "Destination exists. No data was copied.")

        if not remote_src:
            if local_follow and not src:
                msg = "No path given for local symlink"
                return self._exit_action(result, msg, failed=True)

            elif src and not os.path.exists(b_src):
                msg = "The local file {0} does not exist".format(src)
                return self._exit_action(result, msg, failed=True)

            elif src and not os.access(b_src, os.R_OK):
                msg = ("The local file {0} does not have appropriate "
                       "read permission".format(src))
                return self._exit_action(result, msg, failed=True)

            if content:
                try:
                    local_content = _write_content_to_temp_file(content)
                    transfer_res = self._copy_to_remote(
                        local_content,
                        sftp_port,
                        ignore_stderr=ignore_sftp_stderr)
                finally:
                    os.remove(local_content)
            else:
                if is_src_dir:
                    path, dirs, files = next(os.walk(src))
                    if dirs:
                        result[
                            "msg"] = "Subdirectory found inside source directory"
                        result.update(
                            dict(src=src,
                                 dest=dest,
                                 changed=False,
                                 failed=True))
                        return result
                    task_args["size"] = sum(
                        os.stat(path + "/" + f).st_size for f in files)
                else:
                    if mode == "preserve":
                        task_args["mode"] = "0{0:o}".format(
                            stat.S_IMODE(os.stat(b_src).st_mode))
                    task_args["size"] = os.stat(src).st_size
                transfer_res = self._copy_to_remote(
                    src,
                    sftp_port,
                    is_dir=is_src_dir,
                    ignore_stderr=ignore_sftp_stderr)

            temp_path = transfer_res.get("temp_path")
            if transfer_res.get("msg"):
                return transfer_res

        task_args.update(
            dict(is_uss=is_uss,
                 is_pds=is_pds,
                 copy_member=copy_member,
                 src_member=src_member,
                 temp_path=temp_path,
                 is_mvs_dest=is_mvs_dest,
                 local_charset=encode.Defaults.get_default_system_charset()))
        copy_res = self._execute_module(
            module_name="ibm.ibm_zos_core.zos_copy",
            module_args=task_args,
            task_vars=task_vars,
        )

        if copy_res.get("note") and not force:
            result["note"] = copy_res.get("note")
            return result

        if copy_res.get("msg"):
            result.update(
                dict(
                    msg=copy_res.get("msg"),
                    stdout=copy_res.get("stdout")
                    or copy_res.get("module_stdout"),
                    stderr=copy_res.get("stderr")
                    or copy_res.get("module_stderr"),
                    stdout_lines=copy_res.get("stdout_lines"),
                    stderr_lines=copy_res.get("stderr_lines"),
                    rc=copy_res.get("rc"),
                    invocation=dict(module_args=self._task.args),
                ))
            if backup or backup_name:
                result["backup_name"] = copy_res.get("backup_name")
            self._remote_cleanup(dest, copy_res.get("dest_exists"), task_vars)
            return result

        return _update_result(is_binary, copy_res, self._task.args)
コード例 #5
0
    def run(self, tmp=None, task_vars=None):
        """ handler for file transfer operations """
        if task_vars is None:
            task_vars = dict()

        result = super(ActionModule, self).run(tmp, task_vars)
        del tmp

        src = self._task.args.get('src', None)
        b_src = to_bytes(src, errors='surrogate_or_strict')
        dest = self._task.args.get('dest', None)
        content = self._task.args.get('content', None)
        force = _process_boolean(self._task.args.get('force'), default=True)
        backup = _process_boolean(self._task.args.get('backup'), default=False)
        local_follow = _process_boolean(self._task.args.get('local_follow'), default=False)
        remote_src = _process_boolean(self._task.args.get('remote_src'), default=False)
        is_binary = _process_boolean(self._task.args.get('is_binary'), default=False)
        backup_file = self._task.args.get("backup_file", None)
        encoding = self._task.args.get('encoding', None)
        mode = self._task.args.get('mode', None)
        owner = self._task.args.get('owner', None)
        group = self._task.args.get('group', None)

        new_module_args = self._task.args.copy()
        is_pds = is_src_dir = False
        temp_path = is_uss = is_mvs_dest = copy_member = src_member = None

        if dest:
            if not isinstance(dest, string_types):
                msg = "Invalid type supplied for 'dest' option, it must be a string"
                return self._exit_action(result, msg, failed=True)
            else:
                is_uss = '/' in dest
                is_mvs_dest = is_data_set(dest)
                copy_member = is_member(dest)
        else:
            msg = "Destination is required"
            return self._exit_action(result, msg, failed=True)

        if src:
            if content:
                msg = "Either 'src' or 'content' can be provided; not both."
                return self._exit_action(result, msg, failed=True)

            elif not isinstance(src, string_types):
                msg = "Invalid type supplied for 'src' option, it must be a string"
                return self._exit_action(result, msg, failed=True)

            elif len(src) < 1 or len(dest) < 1:
                msg = "'src' or 'dest' must not be empty"
                return self._exit_action(result, msg, failed=True)
            else:
                src_member = is_member(src)
                if not remote_src:
                    src = os.path.realpath(src)
                    is_src_dir = os.path.isdir(src)
                    is_pds = is_src_dir and is_mvs_dest

        if not src and not content:
            msg = "'src' or 'content' is required"
            return self._exit_action(result, msg, failed=True)

        if encoding and is_binary:
            msg = "The 'encoding' parameter is not valid for binary transfer"
            return self._exit_action(result, msg, failed=True)

        if (not backup) and backup_file is not None:
            msg = "Backup file provided but 'backup' parameter is False"
            return self._exit_action(result, msg, failed=True)

        if not is_uss:
            if mode or owner or group:
                msg = "Cannot specify 'mode', 'owner' or 'group' for MVS destination"
                return self._exit_action(result, msg, failed=True)

        if (not force) and self._dest_exists(src, dest, task_vars):
            return self._exit_action(result, "Destination exists. No data was copied.")

        if not remote_src:
            if local_follow and not src:
                msg = "No path given for local symlink"
                return self._exit_action(result, msg, failed=True)

            elif src and not os.path.exists(b_src):
                msg = "The local file {0} does not exist".format(src)
                return self._exit_action(result, msg, failed=True)

            elif src and not os.access(b_src, os.R_OK):
                msg = (
                    "The local file {0} does not have appropriate "
                    "read permission".format(src)
                )
                return self._exit_action(result, msg, failed=True)

            if content:
                try:
                    local_content = _write_content_to_temp_file(content)
                    transfer_res = self._copy_to_remote(local_content)
                finally:
                    os.remove(local_content)
            else:
                if is_src_dir:
                    path, dirs, files = next(os.walk(src))
                    if dirs:
                        result['msg'] = "Subdirectory found inside source directory"
                        result.update(dict(src=src, dest=dest, changed=False, failed=True))
                        return result
                    new_module_args['size'] = sum(
                        os.stat(path + "/" + f).st_size for f in files
                    )
                else:
                    if mode == 'preserve':
                        new_module_args['mode'] = '0{0:o}'.format(stat.S_IMODE(os.stat(b_src).st_mode))
                    new_module_args['size'] = os.stat(src).st_size
                transfer_res = self._copy_to_remote(src, is_dir=is_src_dir)

            temp_path = transfer_res.get("temp_path")
            if transfer_res.get("msg"):
                return transfer_res

        new_module_args.update(
            dict(
                is_uss=is_uss,
                is_pds=is_pds,
                copy_member=copy_member,
                src_member=src_member,
                temp_path=temp_path,
                is_mvs_dest=is_mvs_dest
            )
        )
        copy_res = self._execute_module(
            module_name='zos_copy',
            module_args=new_module_args,
            task_vars=task_vars
        )

        if copy_res.get('note') and not force:
            result['note'] = copy_res.get('note')
            return result

        if copy_res.get('msg'):
            result.update(
                dict(
                    msg=copy_res.get('msg'),
                    stdout=copy_res.get('stdout') or copy_res.get("module_stdout"),
                    stderr=copy_res.get('stderr') or copy_res.get("module_stderr"),
                    stdout_lines=copy_res.get("stdout_lines"),
                    stderr_lines=copy_res.get("stderr_lines"),
                    rc=copy_res.get('rc'),
                    invocation=dict(module_args=self._task.args)
                )
            )
            if backup or backup_file:
                result['backup_file'] = copy_res.get("backup_file")
            self._remote_cleanup(dest, copy_res.get("dest_exists"), task_vars)
            return result

        return _update_result(is_binary, copy_res, self._task.args)