def main(): module = AnsibleModule( argument_spec=dict( file=dict(required=True), remote_path=dict(), hostname=dict(required=True), username=dict(required=True), password=dict(required=True), port=dict(type='int', default=830) ), supports_check_mode=False ) if not HAS_PYHP: safe_fail(module, msg='There was a problem loading from the pyhpecw7 ' + 'module.', error=str(ie)) hostname = socket.gethostbyname(module.params['hostname']) username = module.params['username'] password = module.params['password'] port = module.params['port'] device = HPCOM7(host=hostname, username=username, password=password, port=port, timeout=120) src = module.params.get('file') dst = module.params.get('remote_path') changed = False try: device.open() except ConnectionError as e: safe_fail(module, device, msg=str(e), descr='Error opening connection to device.') try: file_copy = FileCopy(device, src, dst) if not file_copy.file_already_exists(): if not file_copy.remote_dir_exists: file_copy.create_remote_dir() file_copy.transfer_file() changed = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error transferring file.') results = {} results['source_file'] = file_copy.src results['destination_file'] = file_copy.dst results['changed'] = changed safe_exit(module, device, **results)
def main(): module = AnsibleModule( argument_spec=dict( ipe_package=dict(), boot=dict(), system=dict(), remote_dir=dict(default="flash:/"), delete_ipe=dict(choices=BOOLEANS, type="bool", default=False), reboot=dict(required=True, choices=BOOLEANS, type="bool"), delay=dict(type="str"), hostname=dict(required=True), username=dict(required=True), password=dict(required=True), port=dict(type="int", default=830), ), supports_check_mode=True, ) if not HAS_PYHP: safe_fail(module, msg="There was a problem loading from the pyhpecw7 " + "module.", error=str(ie)) ipe_package = module.params.get("ipe_package") boot = module.params.get("boot") system = module.params.get("system") if ipe_package: if boot or system: module.fail_json(msg="ipe_package and boot/system parameters are mutually exclusive") else: if not (boot and system): module.fail_json(msg="boot and system parameters must be provided if ipe_package is not") hostname = socket.gethostbyname(module.params["hostname"]) username = module.params["username"] password = module.params["password"] port = module.params["port"] device = HPCOM7(host=hostname, username=username, password=password, port=port, timeout=150) changed = False reboot = module.params.get("reboot") delay = module.params.get("delay") already_set = False transfered = False try: device.open() except ConnectionError as e: safe_fail(module, device, msg=str(e), descr="Error opening connection to device.") try: ios = InstallOs(device) existing = ios.get_config() except PYHPError: safe_fail(module, device, msg=str(e), descr="Error getting current config.") existing_boot = existing["startup-primary"]["boot"] existing_system = existing["startup-primary"]["system"] remote_dir = module.params["remote_dir"] if ipe_package: ipe_basename = os.path.basename(ipe_package) ipe_boot_sys = re.split("-|\.", ipe_basename)[-3:-1] if ipe_boot_sys: if ( ipe_boot_sys[0].lower() in existing_boot.lower() and ipe_boot_sys[0].lower() in existing_system.lower() and ipe_boot_sys[1].lower() in existing_boot.lower() and ipe_boot_sys[1].lower() in existing_system.lower() ): already_set = True ipe_dst = remote_dir + ipe_basename try: # preps transfer and checks if source file exists ipe_file_copy = FileCopy(device, ipe_package, ipe_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error preparing IPE file transfer.") if not ipe_file_copy.file_already_exists(): try: ipe_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error transfering IPE file.") if not already_set: delete_ipe = module.params.get("delete_ipe") ios.build("ipe", ipe=ipe_file_copy.dst, delete_ipe=delete_ipe, stage=True) elif boot: boot_basename = os.path.basename(boot) system_basename = os.path.basename(system) if boot_basename in existing_boot and system_basename in existing_system: already_set = True boot_dst = remote_dir + boot_basename try: # preps transfer and checks if source file exists boot_file_copy = FileCopy(device, boot, boot_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error preparing boot file transfer.") system_dst = remote_dir + system_basename try: # preps transfer and checks if source file exists system_file_copy = FileCopy(device, system, system_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error preparing system file transfer.") if not boot_file_copy.file_already_exists(): try: boot_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error transfering boot file.") if not system_file_copy.file_already_exists(): try: system_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr="Error transfering system file.") if not already_set: ios.build("bootsys", boot=boot_file_copy.dst, system=system_file_copy.dst, stage=True) commands = None end_state = existing reboot_attempt = "no" if device.staged or transfered: if reboot and delay: reboot_attempt = "yes" os_reboot = Reboot(device) os_reboot.build(stage=True, reboot=True, delay=delay) commands = device.staged_to_string() if module.check_mode: safe_exit(module, device, changed=True, commands=commands, transfered=transfered, end_state=end_state) else: try: device.execute_staged() end_state = ios.get_config() except PYHPError as e: safe_fail(module, device, msg=str(e), descr="Error executing commands.") changed = True results = {} results["commands"] = commands results["transfered"] = transfered results["changed"] = changed results["end_state"] = end_state if reboot and not delay: reboot_attempt = "yes" try: device.reboot() changed = True # for some reason, # this is needed to activate the reboot try: device.close() except PYHPError: pass except PYHPError as e: safe_fail(module, device, msg=str(e), descr="Error rebooting the device.") results["reboot_attempt"] = reboot_attempt safe_exit(module, device, **results)
def main(): module = AnsibleModule(argument_spec=dict( ipe_package=dict(), boot=dict(), system=dict(), remote_dir=dict(default='flash:/'), delete_ipe=dict(choices=BOOLEANS, type='bool', default=False), reboot=dict(required=True, choices=BOOLEANS, type='bool'), delay=dict(type='str'), hostname=dict(required=True), username=dict(required=True), password=dict(required=True), port=dict(type='int', default=830)), supports_check_mode=True) if not HAS_PYHP: safe_fail(module, msg='There was a problem loading from the pyhpecw7 ' + 'module.', error=str(ie)) ipe_package = module.params.get('ipe_package') boot = module.params.get('boot') system = module.params.get('system') if ipe_package: if boot or system: module.fail_json( msg= 'ipe_package and boot/system parameters are mutually exclusive' ) else: if not (boot and system): module.fail_json( msg= 'boot and system parameters must be provided if ipe_package is not' ) hostname = socket.gethostbyname(module.params['hostname']) username = module.params['username'] password = module.params['password'] port = module.params['port'] device = HPCOM7(host=hostname, username=username, password=password, port=port, timeout=150) changed = False reboot = module.params.get('reboot') delay = module.params.get('delay') already_set = False transfered = False try: device.open() except ConnectionError as e: safe_fail(module, device, msg=str(e), descr='Error opening connection to device.') try: ios = InstallOs(device) existing = ios.get_config() except PYHPError: safe_fail(module, device, msg=str(e), descr='Error getting current config.') existing_boot = existing['startup-primary']['boot'] existing_system = existing['startup-primary']['system'] remote_dir = module.params['remote_dir'] current_boot_file = remote_dir + existing_boot current_sys_file = remote_dir + existing_system if ipe_package: ipe_basename = os.path.basename(ipe_package) ipe_boot_sys = re.split('-|\.', ipe_basename)[-3:-1] if ipe_boot_sys: if ipe_boot_sys[0].lower() in existing_boot.lower()\ and ipe_boot_sys[0].lower() in existing_system.lower()\ and ipe_boot_sys[1].lower() in existing_boot.lower()\ and ipe_boot_sys[1].lower() in existing_system.lower(): already_set = True ipe_dst = remote_dir + ipe_basename try: # preps transfer and checks if source file exists ipe_file_copy = FileCopy(device, ipe_package, ipe_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error preparing IPE file transfer.') if not ipe_file_copy.file_already_exists(): try: ipe_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error transfering IPE file.') if not already_set: delete_ipe = module.params.get('delete_ipe') ios.build('ipe', ipe=ipe_file_copy.dst, delete_ipe=delete_ipe, stage=True) # set current boot/sys files as backup startup images ios.build('bootsys', boot=current_boot_file, system=current_sys_file, startup_type='2', stage=True) elif boot: boot_basename = os.path.basename(boot) system_basename = os.path.basename(system) if boot_basename in existing_boot\ and system_basename in existing_system: already_set = True boot_dst = remote_dir + boot_basename try: # preps transfer and checks if source file exists boot_file_copy = FileCopy(device, boot, boot_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error preparing boot file transfer.') system_dst = remote_dir + system_basename try: # preps transfer and checks if source file exists system_file_copy = FileCopy(device, system, system_dst) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error preparing system file transfer.') if not boot_file_copy.file_already_exists(): try: boot_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error transfering boot file.') if not system_file_copy.file_already_exists(): try: system_file_copy.transfer_file() transfered = True except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='Error transfering system file.') if not already_set: ios.build('bootsys', boot=boot_file_copy.dst, system=system_file_copy.dst, stage=True) # set current boot/sys files as backup startup images ios.build('bootsys', boot=current_boot_file, system=current_sys_file, startup_type='2', stage=True) commands = None end_state = existing reboot_attempt = 'no' if device.staged or transfered: if reboot and delay: reboot_attempt = 'yes' os_reboot = Reboot(device) os_reboot.build(stage=True, reboot=True, delay=delay) commands = device.staged_to_string() if module.check_mode: safe_exit(module, device, changed=True, commands=commands, transfered=transfered, end_state=end_state) else: try: device.execute_staged() end_state = ios.get_config() except PYHPError as e: safe_fail(module, device, msg=str(e), descr='Error executing commands.') changed = True results = {} results['commands'] = commands results['transfered'] = transfered results['changed'] = changed results['end_state'] = end_state if reboot and not delay: reboot_attempt = 'yes' try: device.reboot() changed = True # for some reason, # this is needed to activate the reboot try: device.close() except PYHPError: pass except PYHPError as e: safe_fail(module, device, msg=str(e), descr='Error rebooting the device.') results['reboot_attempt'] = reboot_attempt safe_exit(module, device, **results)
def main(): module = AnsibleModule(argument_spec=dict( config_file=dict(required=True, type='str'), diff_file=dict(required=False, type='str'), commit_changes=dict(required=True, choices=BOOLEANS, type='bool'), port=dict(default=830, type='int'), hostname=dict(required=True), username=dict(required=True), password=dict(required=True), ), supports_check_mode=True) if not HAS_PYHP: safe_fail(module, msg='There was a problem loading from the pyhpecw7 ' + 'module.', error=str(ie)) username = module.params['username'] password = module.params['password'] port = module.params['port'] hostname = socket.gethostbyname(module.params['hostname']) device_args = dict(host=hostname, username=username, password=password, port=port) device = HPCOM7(timeout=60, **device_args) config_file = module.params['config_file'] diff_file = module.params['diff_file'] commit_changes = module.params['commit_changes'] changed = False if os.path.isfile(config_file): file_exists = True else: safe_fail( module, msg='Cannot find/access config_file:\n{0}'.format(config_file)) try: device.open() except ConnectionError as e: safe_fail(module, device, msg=str(e), descr='error opening connection to device') if file_exists: basename = os.path.basename(config_file) try: copy = FileCopy(device, src=config_file, dst='flash:/{0}'.format(basename)) copy.transfer_file() cfg = Config(device, config_file) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='file transfer error') if diff_file: diffs, full_diffs = cfg.compare_config() write_diffs(diff_file, diffs, full_diffs) else: diffs = 'None. diff_file param not set in playbook' cfg.build(stage=True) active_files = {} if device.staged: active_files = dict(backup='flash:/safety_file.cfg', startup='flash:/startup.cfg', config_applied='flash:/' + basename) if module.check_mode: safe_exit(module, device, changed=True, active_files=active_files, diffs=diffs, diff_file=diff_file, config_file=config_file) else: if commit_changes: try: switch_response = device.execute_staged() # TODO: check of "ok" or errors? except NCError as err: if err.tag == 'operation-failed': safe_fail(module, device, msg='Config replace operation' + ' failed.\nValidate the config' + ' file being applied.') except PYHPError as e: safe_fail(module, device, msg=str(e), descr='error during execution') changed = True results = {} results['changed'] = changed results['active_files'] = active_files results['commit_changes'] = commit_changes results['diff_file'] = diff_file results['config_file'] = config_file safe_exit(module, device, **results)
def setUp(self, mock_device): self.device = mock_device self.file_copy = FileCopy(self.device, SOURCE_FILE)
class FileCopyTestCase(BaseFeatureCase): @mock.patch('pyhpecw7.comware.HPCOM7') def setUp(self, mock_device): self.device = mock_device self.file_copy = FileCopy(self.device, SOURCE_FILE) def test_init(self): self.assertEqual(self.file_copy._remote_dir, 'flash:/') self.assertEqual(self.file_copy.src, SOURCE_FILE) self.assertEqual(self.file_copy.dst, 'flash:/file.txt') self.assertEqual(self.file_copy.port, 22) self.assertEqual(self.file_copy.remote_dir_exists, True) def test_get_flash_size(self): self.device.cli_display.return_value = self.read_cli_display('dir_flash') result = self.file_copy._get_flash_size() self.assertEqual(result, 742204000) self.device.cli_display.return_value = 'garbaldigook' result = self.file_copy._get_flash_size() self.assertEqual(result, 0) @mock.patch.object(FileCopy, '_get_flash_size') @mock.patch('os.path.getsize') def test_enough_space(self, mock_getsize, mock_get_flash_size): mock_getsize.return_value = 2 mock_get_flash_size.return_value = 1 with self.assertRaises(FileNotEnoughSpaceError): self.file_copy._enough_space() mock_getsize.return_value = 1 mock_get_flash_size.return_value = 2 result = self.file_copy._enough_space() self.assertEqual(result, None) @mock.patch.object(FileCopy, '_get_remote_md5') @mock.patch.object(FileCopy, '_get_local_md5') def test_file_already_exists(self, mock_local_md5, mock_remote_md5): mock_local_md5.return_value = 'abc123' mock_remote_md5.return_value = 'abc123' result = self.file_copy.file_already_exists() self.assertEqual(result, True) self.file_copy.remote_dir_exists = False result = self.file_copy.file_already_exists() self.assertEqual(result, False) self.file_copy.remote_dir_exists = True mock_remote_md5.return_value = None result = self.file_copy.file_already_exists() self.assertEqual(result, False) mock_remote_md5.side_effect = NCError result = self.file_copy.file_already_exists() self.assertEqual(result, False) @mock.patch.object(__builtin__, 'open') def test_safety_checks_file_not_readable(self, mock_open): mock_open.side_effect = IOError with self.assertRaises(FileNotReadableError): self.file_copy._safety_checks() @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open): self.file_copy.remote_dir_exists = False with self.assertRaises(FileRemoteDirDoesNotExist): self.file_copy._safety_checks() @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open): self.file_copy.remote_dir_exists = False with self.assertRaises(FileRemoteDirDoesNotExist): self.file_copy._safety_checks() @mock.patch.object(FileCopy, 'file_already_exists') @mock.patch.object(FileCopy, '_enough_space') @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open, mock_enough_space, mock_file_already_exists): mock_file_already_exists.return_value = False self.file_copy._safety_checks() mock_enough_space.assert_called_with() def test_remote_md5(self): expected_get, get_reply = self.xml_action_and_reply('file_copy_remote_md5') self.device.action.return_value = get_reply expected = '44d5527772e1b9841f99cb03f31cbc1c' result = self.file_copy._get_remote_md5() self.assertEqual(result, expected) self.assert_action_request(expected_get) def test_local_md5(self): test_file = NamedTemporaryFile() self.file_copy.src = test_file.name test_file.write('Test content.') test_file.flush() result = self.file_copy._get_local_md5() self.assertEqual(result, 'bcb898f62d9e1ac765c77e6804cbd872') test_file.close() def test_remote_dir(self): expected_get, get_reply = self.xml_get_and_reply('file_copy_remote_dir') self.device.get.return_value = get_reply expected = True result = self.file_copy._remote_dir_exists() self.assertEqual(result, expected) self.assert_get_request(expected_get) @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'abc' mock_ssh = mock_paramiko.SSHClient.return_value self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with(mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with('/path/to/source/file.txt', 'flash:/file.txt') mock_SCP.return_value.close.assert_called_with() @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file_mismatch_hash(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'def' mock_ssh = mock_paramiko.SSHClient.return_value with self.assertRaises(FileHashMismatchError): self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with(mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with('/path/to/source/file.txt', 'flash:/file.txt') mock_SCP.return_value.close.assert_called_with() @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file_error(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'def' mock_ssh = mock_paramiko.SSHClient.return_value mock_SCP.return_value.put.side_effect = Exception with self.assertRaises(FileTransferError): self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with(mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with('/path/to/source/file.txt', 'flash:/file.txt') def test_create_dir(self): self.file_copy._remote_dir = 'flash:/unit/' expected_get, get_reply = self.xml_action_and_reply('file_copy_create_remote_dir') self.device.action.return_value = get_reply expected = None result = self.file_copy.create_remote_dir() self.assertEqual(result, expected) self.assert_action_request(expected_get)
class FileCopyTestCase(BaseFeatureCase): @mock.patch('pyhpecw7.comware.HPCOM7') def setUp(self, mock_device): self.device = mock_device self.file_copy = FileCopy(self.device, SOURCE_FILE) def test_init(self): self.assertEqual(self.file_copy._remote_dir, 'flash:/') self.assertEqual(self.file_copy.src, SOURCE_FILE) self.assertEqual(self.file_copy.dst, 'flash:/file.txt') self.assertEqual(self.file_copy.port, 22) self.assertEqual(self.file_copy.remote_dir_exists, True) def test_get_flash_size(self): self.device.cli_display.return_value = self.read_cli_display( 'dir_flash') result = self.file_copy._get_flash_size() self.assertEqual(result, 742204000) self.device.cli_display.return_value = 'garbaldigook' result = self.file_copy._get_flash_size() self.assertEqual(result, 0) @mock.patch.object(FileCopy, '_get_flash_size') @mock.patch('os.path.getsize') def test_enough_space(self, mock_getsize, mock_get_flash_size): mock_getsize.return_value = 2 mock_get_flash_size.return_value = 1 with self.assertRaises(FileNotEnoughSpaceError): self.file_copy._enough_space() mock_getsize.return_value = 1 mock_get_flash_size.return_value = 2 result = self.file_copy._enough_space() self.assertEqual(result, None) @mock.patch.object(FileCopy, '_get_remote_md5') @mock.patch.object(FileCopy, '_get_local_md5') def test_file_already_exists(self, mock_local_md5, mock_remote_md5): mock_local_md5.return_value = 'abc123' mock_remote_md5.return_value = 'abc123' result = self.file_copy.file_already_exists() self.assertEqual(result, True) self.file_copy.remote_dir_exists = False result = self.file_copy.file_already_exists() self.assertEqual(result, False) self.file_copy.remote_dir_exists = True mock_remote_md5.return_value = None result = self.file_copy.file_already_exists() self.assertEqual(result, False) mock_remote_md5.side_effect = NCError result = self.file_copy.file_already_exists() self.assertEqual(result, False) @mock.patch.object(__builtin__, 'open') def test_safety_checks_file_not_readable(self, mock_open): mock_open.side_effect = IOError with self.assertRaises(FileNotReadableError): self.file_copy._safety_checks() @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open): self.file_copy.remote_dir_exists = False with self.assertRaises(FileRemoteDirDoesNotExist): self.file_copy._safety_checks() @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open): self.file_copy.remote_dir_exists = False with self.assertRaises(FileRemoteDirDoesNotExist): self.file_copy._safety_checks() @mock.patch.object(FileCopy, 'file_already_exists') @mock.patch.object(FileCopy, '_enough_space') @mock.patch.object(__builtin__, 'open') def test_safety_checks_no_remote_dir(self, mock_open, mock_enough_space, mock_file_already_exists): mock_file_already_exists.return_value = False self.file_copy._safety_checks() mock_enough_space.assert_called_with() def test_remote_md5(self): expected_get, get_reply = self.xml_action_and_reply( 'file_copy_remote_md5') self.device.action.return_value = get_reply expected = '44d5527772e1b9841f99cb03f31cbc1c' result = self.file_copy._get_remote_md5() self.assertEqual(result, expected) self.assert_action_request(expected_get) def test_local_md5(self): test_file = NamedTemporaryFile() self.file_copy.src = test_file.name test_file.write('Test content.'.encode('ascii')) test_file.flush() result = self.file_copy._get_local_md5() self.assertEqual(result, 'bcb898f62d9e1ac765c77e6804cbd872') test_file.close() def test_remote_dir(self): expected_get, get_reply = self.xml_get_and_reply( 'file_copy_remote_dir') self.device.get.return_value = get_reply expected = True result = self.file_copy._remote_dir_exists() self.assertEqual(result, expected) self.assert_get_request(expected_get) @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'abc' mock_ssh = mock_paramiko.SSHClient.return_value self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with( mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with( '/path/to/source/file.txt', 'flash:/file.txt') mock_SCP.return_value.close.assert_called_with() @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file_mismatch_hash(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'def' mock_ssh = mock_paramiko.SSHClient.return_value with self.assertRaises(FileHashMismatchError): self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with( mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with( '/path/to/source/file.txt', 'flash:/file.txt') mock_SCP.return_value.close.assert_called_with() @mock.patch('pyhpecw7.features.file_copy.paramiko') @mock.patch('pyhpecw7.features.file_copy.SCPClient') @mock.patch.object(FileCopy, '_safety_checks') @mock.patch.object(FileCopy, '_get_local_md5') @mock.patch.object(FileCopy, '_get_remote_md5') def test_transfer_file_error(self, mock_remote_md5, mock_local_md5, mock_safety_checks, mock_SCP, mock_paramiko): mock_remote_md5.return_value = 'abc' mock_local_md5.return_value = 'def' mock_ssh = mock_paramiko.SSHClient.return_value mock_SCP.return_value.put.side_effect = Exception with self.assertRaises(FileTransferError): self.file_copy.transfer_file() mock_paramiko.SSHClient.assert_called_with() mock_ssh.set_missing_host_key_policy.assert_called_with( mock_paramiko.AutoAddPolicy.return_value) mock_ssh.connect.assert_called_with(allow_agent=False, hostname=self.device.host, look_for_keys=False, password=self.device.password, port=22, username=self.device.username) mock_SCP.assert_called_with(mock_ssh.get_transport.return_value) mock_SCP.return_value.put.assert_called_with( '/path/to/source/file.txt', 'flash:/file.txt') def test_create_dir(self): self.file_copy._remote_dir = 'flash:/unit/' expected_get, get_reply = self.xml_action_and_reply( 'file_copy_create_remote_dir') self.device.action.return_value = get_reply expected = None result = self.file_copy.create_remote_dir() self.assertEqual(result, expected) self.assert_action_request(expected_get)
def main(): module = AnsibleModule( argument_spec=dict( config_file=dict(required=True, type='str'), diff_file=dict(required=False, type='str'), commit_changes=dict(required=True, choices=BOOLEANS, type='bool'), port=dict(default=830, type='int'), hostname=dict(required=True), username=dict(required=True), password=dict(required=True), ), supports_check_mode=True ) if not HAS_PYHP: safe_fail(module, msg='There was a problem loading from the pyhpecw7 ' + 'module.', error=str(ie)) username = module.params['username'] password = module.params['password'] port = module.params['port'] hostname = socket.gethostbyname(module.params['hostname']) device_args = dict(host=hostname, username=username, password=password, port=port) device = HPCOM7(timeout=60, **device_args) config_file = module.params['config_file'] diff_file = module.params['diff_file'] commit_changes = module.params['commit_changes'] changed = False if os.path.isfile(config_file): file_exists = True else: safe_fail(module, msg='Cannot find/access config_file:\n{0}'.format( config_file)) try: device.open() except ConnectionError as e: safe_fail(module, device, msg=str(e), descr='error opening connection to device') if file_exists: basename = os.path.basename(config_file) try: copy = FileCopy(device, src=config_file, dst='flash:/{0}'.format(basename)) copy.transfer_file() cfg = Config(device, config_file) except PYHPError as fe: safe_fail(module, device, msg=str(fe), descr='file transfer error') if diff_file: diffs, full_diffs = cfg.compare_config() write_diffs(diff_file, diffs, full_diffs) else: diffs = 'None. diff_file param not set in playbook' cfg.build(stage=True) active_files = {} if device.staged: active_files = dict(backup='flash:/safety_file.cfg', startup='flash:/startup.cfg', config_applied='flash:/' + basename) if module.check_mode: safe_exit(module, device, changed=True, active_files=active_files, diffs=diffs, diff_file=diff_file, config_file=config_file) else: if commit_changes: try: switch_response = device.execute_staged() # TODO: check of "ok" or errors? except NCError as err: if err.tag == 'operation-failed': safe_fail(module, device, msg='Config replace operation' + ' failed.\nValidate the config' + ' file being applied.') except PYHPError as e: safe_fail(module, device, msg=str(e), descr='error during execution') changed = True results = {} results['changed'] = changed results['active_files'] = active_files results['commit_changes'] = commit_changes results['diff_file'] = diff_file results['config_file'] = config_file safe_exit(module, device, **results)