def get_interface_counters(self, interface):
        """Pull the counters for an interface

        :param interface: interface object or str with name of interface
        :return: Dictionary of counters, or None if no counters for interface
        """
        interface_name = self._interface_name(interface)

        self.xapi.op("<show><counter><interface>%s</interface></counter></show>" % (interface_name,))
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        counters = response['result']
        if counters:
            entry = {}
            # Check for entry in ifnet
            if 'entry' in counters.get('ifnet', {}):
                entry = counters['ifnet']['entry'][0]
            elif 'ifnet' in counters.get('ifnet', {}):
                if 'entry' in counters['ifnet'].get('ifnet', {}):
                    entry = counters['ifnet']['ifnet']['entry'][0]

            # Convert strings to integers, if they are integers
            entry.update((k, PanDevice._convert_if_int(v)) for k, v in entry.iteritems())
            # If empty dictionary (no results) it usually means the interface is not
            # configured, so return None
            return entry if entry else None
Ejemplo n.º 2
0
    def get_counters(self):
        """Pull the counters for an interface

        Returns:
            dict: counter name as key, counter as value, None if interface is not configured

        """
        from pan.config import PanConfig
        pconf = self.pandevice().op('show counter interface "%s"' % self.name)
        pconf = PanConfig(pconf)
        response = pconf.python()
        logger.debug("response: " + str(response))
        counters = response['response']['result']
        if counters is not None:
            entry = {}
            # Check for entry in ifnet
            if 'entry' in counters.get('ifnet', {}):
                entry = counters['ifnet']['entry'][0]
            elif 'ifnet' in counters.get('ifnet', {}):
                if 'entry' in counters['ifnet'].get('ifnet', {}):
                    entry = counters['ifnet']['ifnet']['entry'][0]

            # Convert strings to integers, if they are integers
            entry.update(
                (k, pandevice.convert_if_int(v)) for k, v in entry.iteritems())
            # If empty dictionary (no results) it usually means the interface is not
            # configured, so return None
            return entry if entry else None
Ejemplo n.º 3
0
    def get_counters(self):
        """Pull the counters for an interface

        Returns:
            dict: counter name as key, counter as value, None if interface is not configured

        """
        from pan.config import PanConfig
        pconf = self.pandevice().op('show counter interface "%s"' % self.name)
        pconf = PanConfig(pconf)
        response = pconf.python()
        logger.debug("response: " + str(response))
        counters = response['response']['result']
        if counters is not None:
            entry = {}
            # Check for entry in ifnet
            if 'entry' in counters.get('ifnet', {}):
                entry = counters['ifnet']['entry'][0]
            elif 'ifnet' in counters.get('ifnet', {}):
                if 'entry' in counters['ifnet'].get('ifnet', {}):
                    entry = counters['ifnet']['ifnet']['entry'][0]

            # Convert strings to integers, if they are integers
            entry.update((k, pandevice.convert_if_int(v)) for k, v in entry.iteritems())
            # If empty dictionary (no results) it usually means the interface is not
            # configured, so return None
            return entry if entry else None
Ejemplo n.º 4
0
    def get_interface_counters(self, interface):
        """Pull the counters for an interface

        :param interface: interface object or str with name of interface
        :return: Dictionary of counters, or None if no counters for interface
        """
        interface_name = self._interface_name(interface)

        self.xapi.op(
            "<show><counter><interface>%s</interface></counter></show>" %
            (interface_name, ))
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        counters = response['result']
        if counters:
            entry = {}
            # Check for entry in ifnet
            if 'entry' in counters.get('ifnet', {}):
                entry = counters['ifnet']['entry'][0]
            elif 'ifnet' in counters.get('ifnet', {}):
                if 'entry' in counters['ifnet'].get('ifnet', {}):
                    entry = counters['ifnet']['ifnet']['entry'][0]

            # Convert strings to integers, if they are integers
            entry.update((k, PanDevice._convert_if_int(v))
                         for k, v in entry.iteritems())
            # If empty dictionary (no results) it usually means the interface is not
            # configured, so return None
            return entry if entry else None
    def show_interface(self, interface):
        self.set_config_changed()
        interface_name = self._interface_name(interface)

        self.xapi.op("<show><interface>%s</interface></show>" % (interface_name,))
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        return response['result']
Ejemplo n.º 6
0
    def show_interface(self, interface):
        self.set_config_changed()
        interface_name = self._interface_name(interface)

        self.xapi.op("<show><interface>%s</interface></show>" %
                     (interface_name, ))
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        return response['result']
Ejemplo n.º 7
0
 def _parse_version_list(self, response_element):
     all_versions = {}
     for software_version in response_element.findall(".//versions/entry"):
         # This line doesn't work correctly in pan-python < 0.7.0.
         newversion = PanConfig(software_version).python("./")
         all_versions[newversion["version"]] = newversion
     return all_versions
Ejemplo n.º 8
0
    def refresh_interfaces(self):
        self.xapi.op('show interface "all"', cmd_xml=True)
        pconf = PanConfig(self.xapi.element_root)
        response = pconf.python()
        hw = {}
        interfaces = {}
        # Check if there is a response and result
        try:
            response = response['response']['result']
        except KeyError as e:
            raise err.PanDeviceError(
                "Error reading response while refreshing interfaces",
                pan_device=self)
        if response:
            self._logger.debug("Refresh interfaces result: %s" % response)
            # Create a hw dict with all the 'hw' info
            hw_result = response.get('hw', {})
            if hw_result is None:
                return
            hw_result = hw_result.get('entry', [])
            for hw_entry in hw_result:
                hw[hw_entry['name']] = hw_entry

            if_result = response.get('ifnet', {})
            if if_result is None:
                return
            if_result = if_result.get('entry', [])
            for entry in if_result:
                try:
                    router = entry['fwd'].split(":", 1)[1]
                except IndexError:
                    router = entry['fwd']
                interface = Interface(name=entry['name'],
                                      zone=entry['zone'],
                                      router=router,
                                      subnets=[entry['ip']],
                                      state=hw.get(entry['name'],
                                                   {}).get('state'))
                interfaces[entry['name']] = interface
        else:
            raise err.PanDeviceError("Could not refresh interfaces",
                                     pan_device=self)
        self.interfaces = interfaces
    def get_all_address_objects(self):
        """Return a list containing all address objects

        Return a list containing all address objects in the device
        configuration.

        Returns:
            Right now it just returns the python representation of the API
            call. Eventually it should return a santized list of objects

        Raises:
            PanXapiError:  Raised by pan.xapi module for API errors
        """
        # TODO: Currently returns raw results, but should return a list
        # and raise an exception on error
        address_xpath = self.xpath + "/address"
        self.xapi.get(xpath=address_xpath)
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        return response['result']
Ejemplo n.º 10
0
    def get_all_address_objects(self):
        """Return a list containing all address objects

        Return a list containing all address objects in the device
        configuration.

        Returns:
            Right now it just returns the python representation of the API
            call. Eventually it should return a santized list of objects

        Raises:
            PanXapiError:  Raised by pan.xapi module for API errors
        """
        # TODO: Currently returns raw results, but should return a list
        # and raise an exception on error
        address_xpath = self.xpath + "/address"
        self.xapi.get(xpath=address_xpath)
        pconf = PanConfig(self.xapi.element_result)
        response = pconf.python()
        return response['result']
Ejemplo n.º 11
0
    def refresh_interfaces(self):
        self.xapi.op('show interface "all"', cmd_xml=True)
        pconf = PanConfig(self.xapi.element_root)
        response = pconf.python()
        hw = {}
        interfaces = {}
        # Check if there is a response and result
        try:
            response = response['response']['result']
        except KeyError as e:
            raise err.PanDeviceError("Error reading response while refreshing interfaces", pan_device=self)
        if response:
            self._logger.debug("Refresh interfaces result: %s" % response)
            # Create a hw dict with all the 'hw' info
            hw_result = response.get('hw', {})
            if hw_result is None:
                return
            hw_result = hw_result.get('entry', [])
            for hw_entry in hw_result:
                hw[hw_entry['name']] = hw_entry

            if_result = response.get('ifnet', {})
            if if_result is None:
                return
            if_result = if_result.get('entry', [])
            for entry in if_result:
                try:
                    router = entry['fwd'].split(":", 1)[1]
                except IndexError:
                    router = entry['fwd']
                interface = Interface(name=entry['name'],
                                      zone=entry['zone'],
                                      router=router,
                                      subnets=[entry['ip']],
                                      state=hw.get(entry['name'], {}).get('state')
                                      )
                interfaces[entry['name']] = interface
        else:
            raise err.PanDeviceError("Could not refresh interfaces",
                                     pan_device=self)
        self.interfaces = interfaces
Ejemplo n.º 12
0
    def system_info(self, all_info=False):
        """Get system information

        Returns:
            system information like version, platform, etc.
        """

        self.xapi.op(cmd="<show><system><info></info></system></show>")
        pconf = PanConfig(self.xapi.element_result)
        system_info = pconf.python()
        self._logger.debug("Systeminfo: %s" % system_info)
        if not system_info:
            error_msg = 'Cannot detect device type, unable to get system info'
            self._logger.error(error_msg)
            raise err.PanDeviceError(error_msg, pan_device=self)

        if not all_info:
            version = system_info['result']['system']['sw-version']
            model = system_info['result']['system']['model']
            serial = system_info['result']['system']['serial']
            return version, model, serial
        else:
            return system_info['result']
    def system_info(self, all_info=False):
        """Get system information

        Returns:
            system information like version, platform, etc.
        """

        self.xapi.op(cmd="<show><system><info></info></system></show>")
        pconf = PanConfig(self.xapi.element_result)
        system_info = pconf.python()
        self._logger.debug("Systeminfo: %s" % system_info)
        if not system_info:
            error_msg = 'Cannot detect device type, unable to get system info'
            self._logger.error(error_msg)
            raise err.PanDeviceError(error_msg, pan_device=self)

        if not all_info:
            version = system_info['result']['system']['sw-version']
            model = system_info['result']['system']['model']
            serial = system_info['result']['system']['serial']
            return version, model, serial
        else:
            return system_info['result']
    def syncjob(self, response, interval=0.5):
        """Block until job completes and return result

        response: XML response tag from firewall when job is created

        :returns True if job completed successfully, False if not
        """
        if interval is not None:
            try:
                interval = float(interval)
                if interval < 0:
                    raise ValueError
            except ValueError:
                raise err.PanDeviceError('Invalid interval: %s' % interval)

        job = response.find('./result/job')
        if job is None:
            return False
        job = job.text

        self._logger.debug('Syncing job: %s', job)

        cmd = 'show jobs id "%s"' % job
        start_time = time.time()

        while True:
            try:
                self.xapi.op(cmd=cmd, cmd_xml=True)
            except pan.xapi.PanXapiError as msg:
                raise pan.xapi.PanXapiError('commit %s: %s' % (cmd, msg))

            path = './result/job/status'
            status = self.xapi.element_root.find(path)
            if status is None:
                raise pan.xapi.PanXapiError('No status element in ' +
                                            "'%s' response" % cmd)
            if status.text == 'FIN':
                pconf = PanConfig(self.xapi.element_result)
                response = pconf.python()
                job = response['result']
                if job is None:
                    return
                job = job['job']
                success = True if job['result'] == "OK" else False
                messages = job['details']['line']
                if issubclass(messages.__class__, basestring):
                    messages = [messages]
                # Create the results dict
                result = {
                    'success': success,
                    'result': job['result'],
                    'jobid': job['id'],
                    'user': job['user'],
                    'warnings': job['warnings'],
                    'starttime': job['tenq'],
                    'endtime': job['tfin'],
                    'messages': messages,
                }
                return result

            self._logger.debug('Job %s status %s', job, status.text)

            if (self.timeout is not None and self.timeout != 0 and
                        time.time() > start_time + self.timeout):
                raise pan.xapi.PanXapiError('Timeout waiting for ' +
                                            'job %s completion' % job)

            self._logger.debug('Sleep %.2f seconds', interval)
            time.sleep(interval)
    def _commit(self, cmd=None, exclude=None, commit_all=False,
                sync=False, sync_all=True, exception=False):
        """Internal use commit helper method.

        :param exclude:
            Can be:
                device-and-network
                policy-and-objects
        :param sync:
            Synchronous commit, ie. wait for job to finish
        :return:
            Result of commit as dict if synchronous.  JobID if asynchronous.
            In either case, if no commit is needed, return None.
            Most important fields in dict:
                success:  True or False
                result:  OK or FAIL
                messages: list of warnings or errors

        """

        if issubclass(cmd.__class__, pan.commit.PanCommit):
            cmd = cmd.cmd()
        elif issubclass(cmd.__class__, ET.Element):
            cmd = ET.tostring(cmd)
        elif issubclass(cmd.__class__, basestring):
            pass
        else:
            cmd = ET.Element("commit")
            if exclude is not None:
                excluded = ET.SubElement(cmd, "partial")
                excluded = ET.SubElement(excluded, exclude)
            cmd = ET.tostring(cmd)
        if commit_all:
            action = "all"
        else:
            action = None
        if sync:
            self._logger.debug("Waiting for commit job to finish...")
        self.xapi.commit(cmd=cmd,
                         action=action,
                         sync=sync,
                         sync_all=sync_all,
                         interval=self.interval,
                         timeout=self.timeout)
        self.config_changed = False
        self.config_locked = False
        self.commit_locked = False
        if sync:
            pconf = PanConfig(self.xapi.element_result)
            response = pconf.python()
            job = response['result']
            if job is None:
                if exception:
                    raise err.PanCommitNotNeeded("Commit not needed",
                                                 pan_device=self)
                else:
                    return
            job = job['job']
            # Create a boolean called success to make
            # testing for success easier
            devices_results = {}
            devices_success = True
            if commit_all and sync_all:
                devices = job['devices']
                if devices is not None:
                    devices = devices['entry']
                    for device in devices:
                        success = True if device['result'] == "OK" else False
                        if not success:
                            devices_success = False
                        devices_results[device['serial-no']] = {
                            'success': success,
                            'serial': device['serial-no'],
                            'name': device['devicename'],
                            'result': device['result'],
                            'starttime': device['tstart'],
                            'endtime': device['tfin'],
                            }
                        # Errors and warnings might not have a full structure.  If it is just a string, then
                        # a TypeError will be produced, so in that case, just grab the string.
                        try:
                            devices_results[device['serial-no']]['warnings'] = device['details']['msg']['warnings']
                        except TypeError as e:
                            devices_results[device['serial-no']]['warnings'] = ""
                        try:
                            devices_results[device['serial-no']]['messages'] = device['details']['msg']['errors'][
                                'line']
                        except TypeError as e:
                            devices_results[device['serial-no']]['messages'] = device['details']

            success = True if job['result'] == "OK" and devices_success else False

            if commit_all:
                messages = []
            else:
                messages = job['details']['line']
            if issubclass(messages.__class__, basestring):
                messages = [messages]

            # Create the results dict
            result = {
                'success': success,
                'result': job['result'],
                'jobid': job['id'],
                'user': job['user'],
                'warnings': job['warnings'],
                'starttime': job['tenq'],
                'endtime': job['tfin'],
                'messages': messages,
                'devices': devices_results
            }

            if exception and not success:
                self._logger.debug("Commit failed - device: %s, job: %s, messages: %s, warnings: %s" %
                                   (self.hostname,
                                    result['jobid'],
                                    result['messages'],
                                    result['warnings']))
                raise err.PanCommitFailed(pan_device=self, result=result)
            else:
                if success:
                    self._logger.debug("Commit succeeded - device: %s, job: %s, messages: %s, warnings: %s" %
                                       (self.hostname,
                                        result['jobid'],
                                        result['messages'],
                                        result['warnings']))
                else:
                    self._logger.debug("Commit failed - device: %s, job: %s, messages: %s, warnings: %s" %
                                       (self.hostname,
                                        result['jobid'],
                                        result['messages'],
                                        result['warnings']))
                return result
        else:
            jobid = self.xapi.element_root.find('./result/job')
            if jobid is None:
                if exception:
                    raise err.PanCommitNotNeeded("Commit not needed",
                                                 pan_device=self)
                else:
                    return
            self._logger.debug("Commit initiated (async), job id: %s" % (jobid,))
            return jobid
    def refresh_devices_from_panorama(self, devices=()):
        try:
            # Test if devices is iterable
            test_iterable = iter(devices)
        except TypeError:
            # This probably means a single device was passed in, not an iterable.
            # Convert to an iterable with a single item.
            devices = (devices,)
        stats_by_ip = {}
        stats_by_host = {}
        devicegroup_stats_by_serial = {}
        template_stats_by_serial = {}
        # Get the list of managed devices
        self.xapi.op("show devices all", cmd_xml=True)
        pconf = PanConfig(self.xapi.element_root)
        response = pconf.python()
        try:
            for device in response['response']['result']['devices']['entry']:
                stats_by_ip[device['ip-address']] = device
                stats_by_host[device['ip-address']] = device
                stats_by_host[device['hostname']] = device
            # Populate the device objects with some of the data
            for device in devices:
                try:
                    device.serial = stats_by_host[device.hostname]['serial']
                    device.connected_to_panorama = stats_by_host[device.hostname]['connected']
                except KeyError as e:
                    raise err.PanDeviceError("Can't determine serial for "
                                             "device", pan_device=device)
        # Ignore errors because it means there are no devices
        except KeyError:
            return {}

        # Get the list of device groups
        self.xapi.op("show devicegroups", cmd_xml=True)
        dg_element = self.xapi.element_result
        for dg in dg_element.findall("./devicegroups/entry"):
            for device in dg.findall("./devices/entry"):
                pconf = PanConfig(config=device)
                stats = pconf.python()
                # Save device stats
                stats = stats['entry']
                # Save device serial
                serial = stats['serial']
                # Save device ip-address
                ip = stats['ip-address']
                # Save device's device-group
                dg_name = dg.get('name')
                # Save the device-group to the device's stats
                stats['devicegroup'] = dg_name
                devicegroup_stats_by_serial[serial] = stats
                stats_by_ip[ip]['devicegroup'] = dg_name

        # Set the device-group for each device
        for device in devices:
            if device.serial is not None:
                stats = devicegroup_stats_by_serial.get(device.serial)
                if stats is not None:
                    device.devicegroup = stats['devicegroup']
                    sync_status = stats['shared-policy-status']
                    device.dg_in_sync = True if sync_status == "In Sync" else False

        return stats_by_ip
 def pending_changes(self):
     self.xapi.op(cmd="check pending-changes", cmd_xml=True)
     pconf = PanConfig(self.xapi.element_result)
     response = pconf.python()
     return response['result']
Ejemplo n.º 18
0
 def pending_changes(self):
     self.xapi.op(cmd="check pending-changes", cmd_xml=True)
     pconf = PanConfig(self.xapi.element_result)
     response = pconf.python()
     return response['result']
Ejemplo n.º 19
0
    def refresh_devices_from_panorama(self, devices=()):
        try:
            # Test if devices is iterable
            test_iterable = iter(devices)
        except TypeError:
            # This probably means a single device was passed in, not an iterable.
            # Convert to an iterable with a single item.
            devices = (devices, )
        stats_by_ip = {}
        stats_by_host = {}
        devicegroup_stats_by_serial = {}
        template_stats_by_serial = {}
        # Get the list of managed devices
        self.xapi.op("show devices all", cmd_xml=True)
        pconf = PanConfig(self.xapi.element_root)
        response = pconf.python()
        try:
            for device in response['response']['result']['devices']['entry']:
                stats_by_ip[device['ip-address']] = device
                stats_by_host[device['ip-address']] = device
                stats_by_host[device['hostname']] = device
            # Populate the device objects with some of the data
            for device in devices:
                try:
                    device.serial = stats_by_host[device.hostname]['serial']
                    device.connected_to_panorama = stats_by_host[
                        device.hostname]['connected']
                except KeyError as e:
                    raise err.PanDeviceError(
                        "Can't determine serial for "
                        "device",
                        pan_device=device)
        # Ignore errors because it means there are no devices
        except KeyError:
            return {}

        # Get the list of device groups
        self.xapi.op("show devicegroups", cmd_xml=True)
        dg_element = self.xapi.element_result
        for dg in dg_element.findall("./devicegroups/entry"):
            for device in dg.findall("./devices/entry"):
                pconf = PanConfig(config=device)
                stats = pconf.python()
                # Save device stats
                stats = stats['entry']
                # Save device serial
                serial = stats['serial']
                # Save device ip-address
                ip = stats['ip-address']
                # Save device's device-group
                dg_name = dg.get('name')
                # Save the device-group to the device's stats
                stats['devicegroup'] = dg_name
                devicegroup_stats_by_serial[serial] = stats
                stats_by_ip[ip]['devicegroup'] = dg_name

        # Set the device-group for each device
        for device in devices:
            if device.serial is not None:
                stats = devicegroup_stats_by_serial.get(device.serial)
                if stats is not None:
                    device.devicegroup = stats['devicegroup']
                    sync_status = stats['shared-policy-status']
                    device.dg_in_sync = True if sync_status == "In Sync" else False

        return stats_by_ip
Ejemplo n.º 20
0
    def _commit(self,
                cmd=None,
                exclude=None,
                commit_all=False,
                sync=False,
                sync_all=True,
                exception=False):
        """Internal use commit helper method.

        :param exclude:
            Can be:
                device-and-network
                policy-and-objects
        :param sync:
            Synchronous commit, ie. wait for job to finish
        :return:
            Result of commit as dict if synchronous.  JobID if asynchronous.
            In either case, if no commit is needed, return None.
            Most important fields in dict:
                success:  True or False
                result:  OK or FAIL
                messages: list of warnings or errors

        """

        if issubclass(cmd.__class__, pan.commit.PanCommit):
            cmd = cmd.cmd()
        elif issubclass(cmd.__class__, ET.Element):
            cmd = ET.tostring(cmd)
        elif issubclass(cmd.__class__, basestring):
            pass
        else:
            cmd = ET.Element("commit")
            if exclude is not None:
                excluded = ET.SubElement(cmd, "partial")
                excluded = ET.SubElement(excluded, exclude)
            cmd = ET.tostring(cmd)
        if commit_all:
            action = "all"
        else:
            action = None
        if sync:
            self._logger.debug("Waiting for commit job to finish...")
        self.xapi.commit(cmd=cmd,
                         action=action,
                         sync=sync,
                         sync_all=sync_all,
                         interval=self.interval,
                         timeout=self.timeout)
        self.config_changed = False
        self.config_locked = False
        self.commit_locked = False
        if sync:
            pconf = PanConfig(self.xapi.element_result)
            response = pconf.python()
            job = response['result']
            if job is None:
                if exception:
                    raise err.PanCommitNotNeeded("Commit not needed",
                                                 pan_device=self)
                else:
                    return
            job = job['job']
            # Create a boolean called success to make
            # testing for success easier
            devices_results = {}
            devices_success = True
            if commit_all and sync_all:
                devices = job['devices']
                if devices is not None:
                    devices = devices['entry']
                    for device in devices:
                        success = True if device['result'] == "OK" else False
                        if not success:
                            devices_success = False
                        devices_results[device['serial-no']] = {
                            'success': success,
                            'serial': device['serial-no'],
                            'name': device['devicename'],
                            'result': device['result'],
                            'starttime': device['tstart'],
                            'endtime': device['tfin'],
                        }
                        # Errors and warnings might not have a full structure.  If it is just a string, then
                        # a TypeError will be produced, so in that case, just grab the string.
                        try:
                            devices_results[
                                device['serial-no']]['warnings'] = device[
                                    'details']['msg']['warnings']
                        except TypeError as e:
                            devices_results[
                                device['serial-no']]['warnings'] = ""
                        try:
                            devices_results[
                                device['serial-no']]['messages'] = device[
                                    'details']['msg']['errors']['line']
                        except TypeError as e:
                            devices_results[device['serial-no']][
                                'messages'] = device['details']

            success = True if job[
                'result'] == "OK" and devices_success else False

            if commit_all:
                messages = []
            else:
                messages = job['details']['line']
            if issubclass(messages.__class__, basestring):
                messages = [messages]

            # Create the results dict
            result = {
                'success': success,
                'result': job['result'],
                'jobid': job['id'],
                'user': job['user'],
                'warnings': job['warnings'],
                'starttime': job['tenq'],
                'endtime': job['tfin'],
                'messages': messages,
                'devices': devices_results
            }

            if exception and not success:
                self._logger.debug(
                    "Commit failed - device: %s, job: %s, messages: %s, warnings: %s"
                    % (self.hostname, result['jobid'], result['messages'],
                       result['warnings']))
                raise err.PanCommitFailed(pan_device=self, result=result)
            else:
                if success:
                    self._logger.debug(
                        "Commit succeeded - device: %s, job: %s, messages: %s, warnings: %s"
                        % (self.hostname, result['jobid'], result['messages'],
                           result['warnings']))
                else:
                    self._logger.debug(
                        "Commit failed - device: %s, job: %s, messages: %s, warnings: %s"
                        % (self.hostname, result['jobid'], result['messages'],
                           result['warnings']))
                return result
        else:
            jobid = self.xapi.element_root.find('./result/job')
            if jobid is None:
                if exception:
                    raise err.PanCommitNotNeeded("Commit not needed",
                                                 pan_device=self)
                else:
                    return
            self._logger.debug("Commit initiated (async), job id: %s" %
                               (jobid, ))
            return jobid
Ejemplo n.º 21
0
    def syncjob(self, response, interval=0.5):
        """Block until job completes and return result

        response: XML response tag from firewall when job is created

        :returns True if job completed successfully, False if not
        """
        if interval is not None:
            try:
                interval = float(interval)
                if interval < 0:
                    raise ValueError
            except ValueError:
                raise err.PanDeviceError('Invalid interval: %s' % interval)

        job = response.find('./result/job')
        if job is None:
            return False
        job = job.text

        self._logger.debug('Syncing job: %s', job)

        cmd = 'show jobs id "%s"' % job
        start_time = time.time()

        while True:
            try:
                self.xapi.op(cmd=cmd, cmd_xml=True)
            except pan.xapi.PanXapiError as msg:
                raise pan.xapi.PanXapiError('commit %s: %s' % (cmd, msg))

            path = './result/job/status'
            status = self.xapi.element_root.find(path)
            if status is None:
                raise pan.xapi.PanXapiError('No status element in ' +
                                            "'%s' response" % cmd)
            if status.text == 'FIN':
                pconf = PanConfig(self.xapi.element_result)
                response = pconf.python()
                job = response['result']
                if job is None:
                    return
                job = job['job']
                success = True if job['result'] == "OK" else False
                messages = job['details']['line']
                if issubclass(messages.__class__, basestring):
                    messages = [messages]
                # Create the results dict
                result = {
                    'success': success,
                    'result': job['result'],
                    'jobid': job['id'],
                    'user': job['user'],
                    'warnings': job['warnings'],
                    'starttime': job['tenq'],
                    'endtime': job['tfin'],
                    'messages': messages,
                }
                return result

            self._logger.debug('Job %s status %s', job, status.text)

            if (self.timeout is not None and self.timeout != 0
                    and time.time() > start_time + self.timeout):
                raise pan.xapi.PanXapiError('Timeout waiting for ' +
                                            'job %s completion' % job)

            self._logger.debug('Sleep %.2f seconds', interval)
            time.sleep(interval)