def show_system_resources(self): self.xapi.op(cmd="show system resources", cmd_xml=True) result = self.xapi.xml_root() if self._version_info >= (9, 0, 0): regex = re.compile( r'load average: ([\d\.]+).*? ([\d\.]+) id,.*KiB Mem : (\d+) total,.*? (\d+) free', re.DOTALL) else: regex = re.compile( r"load average: ([\d.]+).* ([\d.]+)%id.*Mem:.*?([\d.]+)k total.*?([\d]+)k free", re.DOTALL) match = regex.search(result) if match: """ return cpu, mem_free, load """ return { 'load': Decimal(match.group(1)), 'cpu': 100 - Decimal(match.group(2)), 'mem_total': int(match.group(3)), 'mem_free': int(match.group(4)), } else: raise err.PanDeviceError("Problem parsing show system resources", pan_device=self)
def install(self, version="latest", sync_to_peer=True, skip_commit=False, sync=False): if not self.versions: self.check() available_versions = map(PanOSVersion, self.versions.keys()) latest_version = max(available_versions) if self.versions[str(latest_version)]['current']: return self._logger.info("Device %s installing content version: %s" % (self.pandevice.hostname, version)) op = ( 'request content upgrade install commit "%s" sync-to-peer "%s" version "%s"' % ("no" if skip_commit else "yes", "yes" if sync_to_peer else "no", version)) response = self._op(op) if sync: result = self.pandevice.syncjob(response) if not result['success']: raise err.PanDeviceError( "Device %s attempt to install content version %s failed: %s" % (self.pandevice.hostname, version, result['messages'])) return result else: return True
def get_vm_auth_keys(self): """Returns the current VM auth keys. Raises: PanDeviceError Returns: list: list of dicts. Each dict has "authkey" and "expires" keys. """ cmd = 'request bootstrap vm-auth-key show' # Raises PanDeviceError. resp = self.op(cmd) data = resp.find('./result') if data is None: raise err.PanDeviceError('No result in returned XML') ans = [] for x in data.findall('./bootstrap-vm-auth-keys/entry'): ans.append({ 'authkey': x.find('./vm-auth-key').text, 'expires': x.find('./expiry-time').text, }) return ans
def generate_vm_auth_key(self, lifetime): """Generates a VM auth key to be placed in a VM's init-cfg.txt. Args: lifetime(int): The lifetime (in hours). Raises: PanDeviceError Returns: dict: has "authkey" and "expires" keys. """ cmd = 'request bootstrap vm-auth-key generate lifetime "{0}"' # Raises PanDeviceError. resp = self.op(cmd.format(lifetime)) data = resp.find('./result') if data is None: raise err.PanDeviceError('No result in returned XML') tokens = data.text.split() ans = { 'authkey': tokens[3], 'expires': ' '.join(tokens[-2:]).rstrip(), } return ans
def download(self, sync_to_peer=None, sync=False): if not self.versions: self.check() available_versions = map(PanOSVersion, self.versions.keys()) latest_version = max(available_versions) if self.versions[str(latest_version)]['downloaded']: return self._logger.info("Device %s downloading content version: %s" % (self.pandevice.id, latest_version)) if sync_to_peer is None: sync_to_peer_text = '' elif sync_to_peer: sync_to_peer_text = ' "" sync-to-peer "yes"' else: sync_to_peer_text = ' "" sync-to-peer "no"' command = 'request content upgrade download latest{0}'.format( sync_to_peer_text) response = self._op(command) if sync: result = self.pandevice.syncjob(response) if not result['success']: raise err.PanDeviceError( "Device %s attempt to download content version %s failed: %s" % (self.pandevice.id, latest_version, result['messages'])) return result else: return True
def set_shared_policy_synced(self, sync_status): if sync_status == "In Sync": self.shared_policy_synced = True elif sync_status == "Out of Sync": self.shared_policy_synced = False elif not sync_status: self.shared_policy_synced = None else: raise err.PanDeviceError("Unknown shared policy status: %s" % str(sync_status))
def install(self, version, load_config=None, sync=False): self._logger.info("Device %s installing version: %s" % (self.pandevice.hostname, version)) response = self._op('request system software install%s version "%s"' % (" load-config " + load_config if load_config is not None else "", version)) if sync: result = self.pandevice.syncjob(response) if not result['success']: raise err.PanDeviceError("Device %s attempt to install version %s failed: %s" % (self.pandevice.hostname, version, result['messages'])) return result else: return True
def download(self, version, sync_to_peer=True, sync=False): self._logger.info("Device %s downloading version: %s" % (self.pandevice.hostname, version)) response = self._op('request system software download sync-to-peer "%s" version "%s"' % ("yes" if sync_to_peer else "no", version)) if sync: result = self.pandevice.syncjob(response) if not result['success']: raise err.PanDeviceError("Device %s attempt to download version %s failed: %s" % (self.pandevice.hostname, version, result['messages'])) return result else: return True
def download_install_reboot(self, version, load_config=None, sync=False): if issubclass(type(version), basestring): version = PanOSVersion(version) self.download_install(version, load_config, sync=True) # Reboot the device self.pandevice.restart() if sync: new_version = self.pandevice.syncreboot() if version != new_version: raise err.PanDeviceError("Attempt to upgrade to version %s failed." "Device %s is on version %s after reboot." % (version, self.pandevice.hostname, new_version)) self.pandevice.version = new_version return new_version else: return None
def download(self, version="latest", sync_to_peer=True, sync=False): if not self.versions: self.check() available_versions = map(PanOSVersion, self.versions.keys()) latest_version = max(available_versions) if self.versions[str(latest_version)]['downloaded']: return self._logger.info("Device %s downloading content version: %s" % (self.pandevice.hostname, version)) response = self._op('request content upgrade download latest sync-to-peer "%s"' % "yes" if sync_to_peer else "no") if sync: result = self.pandevice.syncjob(response) if not result['success']: raise err.PanDeviceError("Device %s attempt to download content version %s failed: %s" % (self.pandevice.hostname, version, result['messages'])) return result else: return True
def upgrade_to_version(self, target_version, dryrun=False): """Upgrade to the target version, completely all intermediate upgrades For example, if firewall is running version 6.0.5 and target version is 7.0.2, then this method will proceed through the following steps: - Upgrade to 6.1.0 and reboot - Upgrade to 7.0.0 and reboot - Upgrade to 7.0.1 and reboot This method does not support HA pairs. """ # Get list of software if needed if not self.versions: self.check() # For a dry run, need to record the starting version starting_version = self.pandevice.version # Get versions as StrictVersion objects available_versions = map(PanOSVersion, self.versions.keys()) current_version = PanOSVersion(self.pandevice.version) latest_version = max(available_versions) next_minor_version = self._next_minor_version(current_version) # Check that this is an upgrade, not a downgrade if current_version > target_version: raise err.PanDeviceError( "Device %s upgrade failed: Can't upgrade from %s to %s." % (self.pandevice.id, self.pandevice.version, target_version)) # Determine the next version to upgrade to if target_version == "latest": next_version = min(latest_version, next_minor_version) elif latest_version < target_version: next_version = next_minor_version elif not self._direct_upgrade_possible(current_version, target_version): next_version = next_minor_version else: next_version = PanOSVersion(str(target_version)) if next_version not in available_versions and not dryrun: self._logger.info( "Device %s upgrading to %s, currently on %s. Checking for newer versions." % (self.pandevice.id, target_version, self.pandevice.version)) self.check() available_versions = map(PanOSVersion, self.versions.keys()) latest_version = max(available_versions) # Check if done upgrading if current_version == target_version: self._logger.info("Device %s is running target version: %s" % (self.pandevice.id, target_version)) return True elif target_version == "latest" and current_version == latest_version: self._logger.info("Device %s is running latest version: %s" % (self.pandevice.id, latest_version)) if dryrun: self._logger.info( "NOTE: dryrun with 'latest' does not show all upgrades,") self._logger.info( "as new versions are learned through the upgrade process,") self._logger.info( "so results may be different than dryrun output when using 'latest'." ) return True # Ensure the content pack is upgraded to the latest self.pandevice.content.download_and_install_latest(sync=True) # Upgrade to the next version self._logger.info("Device %s will be upgraded to version: %s" % (self.pandevice.id, next_version)) if dryrun: self.pandevice.version = str(next_version) else: self.download_install_reboot(next_version, sync=True) self.check() result = self.upgrade_to_version(target_version, dryrun=dryrun) if result and dryrun: self.pandevice.version = starting_version return result
def __init__(self, *args, **kwargs): if type(self) == NTPServer: raise err.PanDeviceError( "Do not instantiate class. Please use a subclass.") super(NTPServer, self).__init__(*args, **kwargs)
def get_registered_ip(self, ip=None, tags=None, prefix=None): """Return registered/tagged addresses When called without arguments, retrieves all registered addresses. Note: Passing a single ip and/or single tag to this method results in a response from the firewall that contains only the relevant entries. ie. the filtering is done on the firewall before it responds. Passing a list of multiple ip addresses or tags will result in retreival of the entire tag database from the firewall which is then filtered and returned with only the relevant entries. Therefor, using a single ip or tag is more efficient. **Support:** PAN-OS 6.0 and higher Args: ip (:obj:`list` or :obj:`str`): IP address(es) to get tags for tags (:obj:`list` or :obj:`str`): Tag(s) to get prefix (str): Override class tag prefix Returns: dict: ip addresses as keys with tags as values Raises: PanDeviceError if running PAN-OS < 8.0 and a logfile is returned instead of IP/tag mapings. """ if self.device is None: raise err.PanDeviceNotSet('No device set for this userid instance') version = self.device.retrieve_panos_version() if prefix is None: prefix = self.prefix # Build up the command. limit = 0 start_elm = None start_offset = 1 root = ET.Element("show") cmd = ET.SubElement(root, "object") if version >= (6, 1, 0): cmd = ET.SubElement(cmd, "registered-ip") if version >= (8, 0, 0): # PAN-OS 8.0+ supports paging. limit = 500 ET.SubElement(cmd, "limit").text = '{0}'.format(limit) start_elm = ET.SubElement(cmd, 'start-point') start_elm.text = '{0}'.format(start_offset) else: cmd = ET.SubElement(cmd, "registered-address") # Add ip/tag filter arguments to command. ip = list(set(string_or_list_or_none(ip))) tags = list(set(string_or_list_or_none(tags))) tags = [prefix + t for t in tags] if len(tags) == 1: tag_element = ET.SubElement(cmd, "tag") ET.SubElement(tag_element, "entry", {"name": tags[0]}) if len(ip) == 1: ip_element = ET.SubElement(cmd, "ip") ip_element.text = ip[0] addresses = {} while True: resp = self.device.op(cmd=ET.tostring(root, encoding='utf-8'), vsys=self.device.vsys, cmd_xml=False) # PAN-OS 7.1 and lower can return "outfile" instead of actual results. outfile = resp.find('./result/msg/line/outfile') if outfile is not None: msg = [ 'PAN-OS returned "{0}" instead of IP/tag mappings'.format( outfile.text), 'please upgrade to PAN-OS 8.0+', ] raise err.PanDeviceError(', '.join(msg)) entries = resp.findall("./result/entry") for entry in entries: c_ip = entry.get("ip") if ip and c_ip not in ip: continue members = entry.findall("./tag/member") c_tags = [] for member in members: tag = member.text if not prefix or tag.startswith(prefix): if not tags or tag in tags: c_tags.append(tag) if c_tags: addresses[c_ip] = c_tags if start_elm is None or limit == 0 or len(entries) < limit: break start_offset += len(entries) start_elm.text = '{0}'.format(start_offset) # Done. return addresses
def xpath_panorama(self): raise err.PanDeviceError( "Attempt to modify Panorama configuration on non-Panorama device")