def test_safe_rm_exceptions(self): error = False try: utils.safe_rm('/tmp/no_way_this_is_a_file_nope.sh') except (IOError, OSError): error = True self.assertFalse(error, 'utils.safe_rm raised exception when it should not have')
def test_safe_rm_exceptions(self): try: utils.safe_rm('/tmp/no_way_this_is_a_file_nope.sh') except (IOError, OSError): self.assertTrue( False, "utils.safe_rm raised exception when it should not have")
def test_safe_rm(self, os_remove_mock): utils.safe_rm('dummy_tgt') self.assertTrue(os_remove_mock.called)
def test_safe_rm_exceptions(self): try: utils.safe_rm('/tmp/no_way_this_is_a_file_nope.sh') except (IOError, OSError): self.assertTrue(False, "utils.safe_rm raised exception when it should not have")
def install_os(path=None, **kwargs): ''' Installs the given image on the device. After the installation is complete\ the device is rebooted, if reboot=True is given as a keyworded argument. Usage: .. code-block:: bash salt 'device_name' junos.install_os 'salt://images/junos_image.tgz' reboot=True salt 'device_name' junos.install_os 'salt://junos_16_1.tgz' dev_timeout=300 Parameters: Required * path: Path where the image file is present on the proxy minion. Optional * kwargs: keyworded arguments to be given such as dev_timeout, reboot etc * dev_timeout: Set NETCONF RPC timeout. Can be used to RPCs which take a while to execute. (default = 30 seconds) * reboot: Whether to reboot after installation (default = False) * no_copy: When True the software package will not be SCP’d to the device. \ (default = False) ''' conn = __proxy__['junos.conn']() ret = dict() ret['out'] = True if path is None: ret['message'] = \ 'Please provide the salt path where the junos image is present.' ret['out'] = False return ret image_cached_path = files.mkstemp() __salt__['cp.get_template'](path, image_cached_path) if not os.path.isfile(image_cached_path): ret['message'] = 'Invalid image path.' ret['out'] = False return ret if os.path.getsize(image_cached_path) == 0: ret['message'] = 'Failed to copy image' ret['out'] = False return ret path = image_cached_path op = dict() if '__pub_arg' in kwargs: if kwargs['__pub_arg']: if isinstance(kwargs['__pub_arg'][-1], dict): op.update(kwargs['__pub_arg'][-1]) else: op.update(kwargs) try: conn.sw.install(path, progress=True) ret['message'] = 'Installed the os.' except Exception as exception: ret['message'] = 'Installation failed due to: "{0}"'.format(exception) ret['out'] = False return ret finally: safe_rm(image_cached_path) if 'reboot' in op and op['reboot'] is True: try: conn.sw.reboot() except Exception as exception: ret['message'] = \ 'Installation successful but reboot failed due to : "{0}"' \ .format(exception) ret['out'] = False return ret ret['message'] = 'Successfully installed and rebooted!' return ret
def install_config(path=None, **kwargs): ''' Installs the given configuration file into the candidate configuration. Commits the changes if the commit checks or throws an error. Usage: .. code-block:: bash salt 'device_name' junos.install_config 'salt://production/network/routers/config.set' salt 'device_name' junos.install_config 'salt://templates/replace_config.conf' replace=True comment='Committed via SaltStack' salt 'device_name' junos.install_config 'salt://my_new_configuration.conf' dev_timeout=300 diffs_file='/salt/confs/old_config.conf' overwrite=True salt 'device_name' junos.install_config 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}' Parameters: Required * path: Path where the configuration/template file is present. If the file has a \ '*.conf' extension, the content is treated as text format. If the file has a '*.xml' \ extension, the content is treated as XML format. If the file has a '*.set' \ extension, the content is treated as Junos OS 'set' commands.(default = None) Optional * kwargs: Keyworded arguments which can be provided like- * dev_timeout: Set NETCONF RPC timeout. Can be used for commands which take a while to execute. (default = 30 seconds) * overwrite: Set to True if you want this file is to completely replace the\ configuration file. (default = False) * replace: Specify whether the configuration file uses "replace:" statements. Those statements under the 'replace' tag will only be changed.\ (default = False) * comment: Provide a comment to the commit. (default = None) * confirm: Provide time in minutes for commit confirmation. If this option is specified, the commit will be rollbacked in \ the given time unless the commit is confirmed. * diffs_file: Path to the file where the diff (difference in old configuration and the committed configuration) will be stored.(default = None) Note that the file will be stored on the proxy minion. To push the files to the master use the salt's following execution module: \ :py:func:`cp.push <salt.modules.cp.push>` * template_vars: Variables to be passed into the template processing engine in addition to those present in __pillar__, __opts__, __grains__, etc. You may reference these variables in your template like so: {{ template_vars["var_name"] }} ''' conn = __proxy__['junos.conn']() ret = dict() ret['out'] = True if path is None: ret['message'] = \ 'Please provide the salt path where the configuration is present' ret['out'] = False return ret op = dict() if '__pub_arg' in kwargs: if kwargs['__pub_arg']: if isinstance(kwargs['__pub_arg'][-1], dict): op.update(kwargs['__pub_arg'][-1]) else: op.update(kwargs) template_vars = dict() if "template_vars" in op: template_vars = op["template_vars"] template_cached_path = files.mkstemp() __salt__['cp.get_template']( path, template_cached_path, template_vars=template_vars) if not os.path.isfile(template_cached_path): ret['message'] = 'Invalid file path.' ret['out'] = False return ret if os.path.getsize(template_cached_path) == 0: ret['message'] = 'Template failed to render' ret['out'] = False return ret write_diff = '' if 'diffs_file' in op and op['diffs_file'] is not None: write_diff = op['diffs_file'] del op['diffs_file'] op['path'] = template_cached_path if 'format' not in op: if path.endswith('set'): template_format = 'set' elif path.endswith('xml'): template_format = 'xml' else: template_format = 'text' op['format'] = template_format if 'replace' in op and op['replace']: op['merge'] = False del op['replace'] elif 'overwrite' in op and op['overwrite']: op['overwrite'] = True elif 'overwrite' in op and not op['overwrite']: op['merge'] = True del op['overwrite'] try: conn.cu.load(**op) except Exception as exception: ret['message'] = 'Could not load configuration due to : "{0}"'.format( exception) ret['format'] = template_format ret['out'] = False return ret finally: safe_rm(template_cached_path) config_diff = conn.cu.diff() if config_diff is None: ret['message'] = 'Configuration already applied!' ret['out'] = True return ret commit_params = {} if 'confirm' in op: commit_params['confirm'] = op['confirm'] if 'comment' in op: commit_params['comment'] = op['comment'] try: check = conn.cu.commit_check() except Exception as exception: ret['message'] = \ 'Commit check threw the following exception: "{0}"'\ .format(exception) ret['out'] = False return ret if check: try: conn.cu.commit(**commit_params) ret['message'] = 'Successfully loaded and committed!' except Exception as exception: ret['message'] = \ 'Commit check successful but commit failed with "{0}"'\ .format(exception) ret['out'] = False return ret else: ret['message'] = 'Loaded configuration but commit check failed.' ret['out'] = False conn.cu.rollback() try: if write_diff and config_diff is not None: with fopen(write_diff, 'w') as fp: fp.write(config_diff) except Exception as exception: ret['message'] = 'Could not write into diffs_file due to: "{0}"'.format( exception) ret['out'] = False return ret
def load(path=None, **kwargs): """ Loads the configuration from the file provided onto the device. Usage: .. code-block:: bash salt 'device_name' junos.load 'salt://production/network/routers/config.set' salt 'device_name' junos.load 'salt://templates/replace_config.conf' replace=True salt 'device_name' junos.load 'salt://my_new_configuration.conf' overwrite=True salt 'device_name' junos.load 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}' Parameters: Required * path: Path where the configuration/template file is present. If the file has a \ '*.conf' extension, the content is treated as text format. If the file has a '*.xml' \ extension, the content is treated as XML format. If the file has a '*.set' \ extension, the content is treated as Junos OS 'set' commands.(default = None) Optional * kwargs: Keyworded arguments which can be provided like- * overwrite: Set to True if you want this file is to completely replace the\ configuration file. (default = False) * replace: Specify whether the configuration file uses "replace:" statements. Those statements under the 'replace' tag will only be changed.\ (default = False) * format: Determines the format of the contents. * update: Compare a complete loaded configuration against the candidate configuration. For each hierarchy level or configuration object that is different in the two configurations, the version in the loaded configuration replaces the version in the candidate configuration. When the configuration is later committed, only system processes that are affected by the changed configuration elements parse the new configuration. This action is supported from PyEZ 2.1 (default = False) * template_vars: Variables to be passed into the template processing engine in addition to those present in __pillar__, __opts__, __grains__, etc. You may reference these variables in your template like so: {{ template_vars["var_name"] }} """ conn = __proxy__['junos.conn']() ret = dict() ret['out'] = True if path is None: ret['message'] = \ 'Please provide the salt path where the configuration is present' ret['out'] = False return ret op = dict() if '__pub_arg' in kwargs: if kwargs['__pub_arg']: if isinstance(kwargs['__pub_arg'][-1], dict): op.update(kwargs['__pub_arg'][-1]) else: op.update(kwargs) template_vars = dict() if "template_vars" in op: template_vars = op["template_vars"] template_cached_path = files.mkstemp() __salt__['cp.get_template']( path, template_cached_path, template_vars=template_vars) if not os.path.isfile(template_cached_path): ret['message'] = 'Invalid file path.' ret['out'] = False return ret if os.path.getsize(template_cached_path) == 0: ret['message'] = 'Template failed to render' ret['out'] = False return ret op['path'] = template_cached_path if 'format' not in op: if path.endswith('set'): template_format = 'set' elif path.endswith('xml'): template_format = 'xml' else: template_format = 'text' op['format'] = template_format if 'replace' in op and op['replace']: op['merge'] = False del op['replace'] elif 'overwrite' in op and op['overwrite']: op['overwrite'] = True elif 'overwrite' in op and not op['overwrite']: op['merge'] = True del op['overwrite'] try: conn.cu.load(**op) ret['message'] = "Successfully loaded the configuration." except Exception as exception: ret['message'] = 'Could not load configuration due to : "{0}"'.format( exception) ret['format'] = template_format ret['out'] = False return ret finally: safe_rm(template_cached_path) return ret