Esempio n. 1
0
 def setUp(self, mock_connect):
     self.mock_module_helper = patch.multiple(basic.AnsibleModule,
                                              exit_json=exit_json,
                                              fail_json=fail_json)
     self.mock_module_helper.start()
     self.addCleanup(self.mock_module_helper.stop)
     self.sshclient = IBMSVCssh(self.mock_module_helper, '1.2.3.4',
                                'username', 'password',
                                False, '', 'test.log')
Esempio n. 2
0
class TestIBMSVModuleUtilsSsh(unittest.TestCase):
    """ a group of related Unit Tests"""

    @patch('ansible_collections.ibm.spectrum_virtualize.plugins.module_utils.'
           'ibm_svc_ssh.IBMSVCssh._svc_connect')
    def setUp(self, mock_connect):
        self.mock_module_helper = patch.multiple(basic.AnsibleModule,
                                                 exit_json=exit_json,
                                                 fail_json=fail_json)
        self.mock_module_helper.start()
        self.addCleanup(self.mock_module_helper.stop)
        self.sshclient = IBMSVCssh(self.mock_module_helper, '1.2.3.4',
                                   'username', 'password',
                                   False, '', 'test.log')

    def set_default_args(self):
        return dict({
            'clustername': 'clustername',
            'username': '******',
            'password': '******',
            'look_for_keys': False,
        })

    @patch('ansible_collections.ibm.spectrum_virtualize.plugins.module_utils.'
           'ibm_svc_ssh.IBMSVCssh._svc_connect')
    def test_svc_ssh_connect(self, mock_connect):
        if paramiko is None:
            print("paramiko is not installed")

        ret = self.sshclient.is_connected()
        self.assertTrue(ret)

    @patch('ansible_collections.ibm.spectrum_virtualize.plugins.module_utils.'
           'ibm_svc_ssh.IBMSVCssh._svc_connect')
    def test_svc_ssh_disconnect_successfully(self, mock_disconnect):
        if paramiko is None:
            print("paramiko is not installed")

        patch.object(paramiko.SSHClient, 'close')
        ret = self.sshclient._svc_disconnect()
        self.assertTrue(ret)
    def __init__(self, timeout=30, cmd_timeout=30.0):
        """
        Constructor for SSH client class.
        """

        argument_spec = svc_ssh_argument_spec()

        argument_spec.update(
            dict(command=dict(type='str', required=False),
                 usesshkey=dict(type='str',
                                required=False,
                                default='no',
                                choices=['yes', 'no']),
                 key_filename=dict(type='str', required=False)))

        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True)

        # logging setup
        log_path = self.module.params['log_path']
        log = get_logger(self.__class__.__name__, log_path)
        self.log = log.info

        # Required parameters for module
        self.command = self.module.params['command']

        # local SSH keys will be used in case of password less SSH connection
        self.usesshkey = self.module.params['usesshkey']
        self.key_filename = self.module.params['key_filename']

        # Required
        self.clustername = self.module.params['clustername']
        self.username = self.module.params['username']
        self.password = self.module.params['password']
        self.log_path = log_path

        # Handling missing mandatory parameter command
        if not self.command:
            self.module.fail_json(msg='Missing mandatory parameter: command')

        if self.password is None:
            if self.usesshkey == 'yes':
                self.log(
                    "password is none and use ssh private key. Check for its path"
                )
                if self.key_filename:
                    self.look_for_keys = True
                else:
                    self.log(
                        "key file_name is not provided, use default one, ~/.ssh/id_rsa.pub"
                    )
                    self.look_for_keys = True
            else:
                self.module.fail_json(
                    msg="You must pass in either password or key for ssh")
        else:
            self.look_for_keys = False

        # Connect to the storage
        self.ssh_client = IBMSVCssh(
            module=self.module,
            clustername=self.module.params['clustername'],
            username=self.module.params['username'],
            password=self.module.params['password'],
            look_for_keys=self.look_for_keys,
            key_filename=self.key_filename,
            log_path=log_path)
class IBMSVCsshClient(object):
    def __init__(self, timeout=30, cmd_timeout=30.0):
        """
        Constructor for SSH client class.
        """

        argument_spec = svc_ssh_argument_spec()

        argument_spec.update(
            dict(command=dict(type='str', required=False),
                 usesshkey=dict(type='str',
                                required=False,
                                default='no',
                                choices=['yes', 'no']),
                 key_filename=dict(type='str', required=False)))

        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True)

        # logging setup
        log_path = self.module.params['log_path']
        log = get_logger(self.__class__.__name__, log_path)
        self.log = log.info

        # Required parameters for module
        self.command = self.module.params['command']

        # local SSH keys will be used in case of password less SSH connection
        self.usesshkey = self.module.params['usesshkey']
        self.key_filename = self.module.params['key_filename']

        # Required
        self.clustername = self.module.params['clustername']
        self.username = self.module.params['username']
        self.password = self.module.params['password']
        self.log_path = log_path

        # Handling missing mandatory parameter command
        if not self.command:
            self.module.fail_json(msg='Missing mandatory parameter: command')

        if self.password is None:
            if self.usesshkey == 'yes':
                self.log(
                    "password is none and use ssh private key. Check for its path"
                )
                if self.key_filename:
                    self.look_for_keys = True
                else:
                    self.log(
                        "key file_name is not provided, use default one, ~/.ssh/id_rsa.pub"
                    )
                    self.look_for_keys = True
            else:
                self.module.fail_json(
                    msg="You must pass in either password or key for ssh")
        else:
            self.look_for_keys = False

        # Connect to the storage
        self.ssh_client = IBMSVCssh(
            module=self.module,
            clustername=self.module.params['clustername'],
            username=self.module.params['username'],
            password=self.module.params['password'],
            look_for_keys=self.look_for_keys,
            key_filename=self.key_filename,
            log_path=log_path)

    def modify_command(self, argument):
        return ' '.join([
            c.strip() if not c.startswith('ls') else c + " -json"
            for c in argument.strip().split()
        ])

    def send_svcinfo_command(self):
        info_output = ""
        message = ""
        failed = False

        if self.ssh_client.is_client_connected:
            if not self.command.startswith('svcinfo'):
                failed = True
                message = "The command must start with svcinfo"
            if (self.command.find('|') != -1):
                failed = True
                message = "Pipe(|) is not supported in command."
            if (self.command.find('-filtervalue') != -1):
                failed = True
                message = "'filtervalue' is not supported in command."
            if not failed:
                new_command = self.modify_command(self.command)
                self.log("Executing CLI command: %s", new_command)
                stdin, stdout, stderr = self.ssh_client.client.exec_command(
                    new_command)
                for line in stdout.readlines():
                    info_output += line
                self.log(info_output)
                rc = stdout.channel.recv_exit_status()
                if rc > 0:
                    message = stderr.read()
                    if len(message) > 0:
                        message = message.decode('utf-8')
                        self.log("Error in executing CLI command: %s",
                                 new_command)
                        self.log("%s", message)
                    else:
                        message = "Unknown error"
                    self.ssh_client._svc_disconnect()
                    self.module.fail_json(msg=message,
                                          rc=rc,
                                          stdout=info_output)
                self.ssh_client._svc_disconnect()
                self.module.exit_json(msg=message,
                                      rc=rc,
                                      stdout=info_output,
                                      changed=False)
        else:
            message = "SSH client is not connected"
        self.ssh_client._svc_disconnect()
        self.module.fail_json(msg=message)
Esempio n. 5
0
class IBMSVCsshClient(object):
    def __init__(self, timeout=30, cmd_timeout=30.0):
        """
        Constructor for SSH client class.
        """

        argument_spec = svc_ssh_argument_spec()

        argument_spec.update(
            dict(command=dict(type='list', elements='str', required=False),
                 usesshkey=dict(type='str',
                                required=False,
                                default='no',
                                choices=['yes', 'no']),
                 key_filename=dict(type='str', required=False)))

        self.module = AnsibleModule(argument_spec=argument_spec,
                                    supports_check_mode=True)

        # logging setup
        log_path = self.module.params['log_path']
        log = get_logger(self.__class__.__name__, log_path)
        self.log = log.info

        # Required fields for module
        self.command = self.module.params['command']

        # local SSH keys will be used in case of password less SSH connection
        self.usesshkey = self.module.params['usesshkey']
        self.key_filename = self.module.params['key_filename']

        # Required
        self.clustername = self.module.params['clustername']
        self.username = self.module.params['username']
        self.password = self.module.params['password']
        self.log_path = log_path

        # Handling missing mandatory parameter
        if not self.command:
            self.module.fail_json(msg='Missing mandatory parameter: command')

        if self.password is None:
            if self.usesshkey == 'yes':
                self.log(
                    "password is none and use ssh private key. Check for its path"
                )
                if self.key_filename:
                    self.log("key file_name is provided, use it")
                    self.look_for_keys = True
                else:
                    self.log(
                        "key file_name is not provided, use default one, ~/.ssh/id_rsa.pub"
                    )
                    self.look_for_keys = True
            else:
                self.log("password is none and SSH key is not provided")
                self.module.fail_json(
                    msg="You must pass in either password or key for ssh")
        else:
            self.log("password is given")
            self.look_for_keys = False

        self.ssh_client = IBMSVCssh(
            module=self.module,
            clustername=self.module.params['clustername'],
            username=self.module.params['username'],
            password=self.module.params['password'],
            look_for_keys=self.look_for_keys,
            key_filename=self.key_filename,
            log_path=log_path)

    def send_svctask_command(self):
        message = ""
        if self.ssh_client.is_client_connected:
            for cmd in self.command:
                if not cmd.startswith('svctask'):
                    self.ssh_client._svc_disconnect()
                    self.module.fail_json(
                        msg="The command must start with svctask",
                        changed=False)
                self.log("Executing CLI command: %s", cmd)
                stdin, stdout, stderr = self.ssh_client.client.exec_command(
                    cmd)
                for line in stdout.readlines():
                    message += line
                    self.log(line)
                rc = stdout.channel.recv_exit_status()
                if rc > 0:
                    result = stderr.read()
                    if len(result) > 0:
                        result = result.decode('utf-8')
                        self.log("Error in executing CLI command: %s", cmd)
                        self.log("%s", result)
                        message += result
                    else:
                        message = "Unknown error"
                    self.ssh_client._svc_disconnect()
                    self.module.fail_json(msg=message, rc=rc)
        else:
            message = "SSH client is not connected"
        self.ssh_client._svc_disconnect()
        self.module.exit_json(msg=message, rc=rc, changed=True)