Application package not up to date-paloaltonetworks-panos

warn
panos
paloaltonetworks
Application package not up to date-paloaltonetworks-panos
0

#1

Application package not up to date-paloaltonetworks-panos

Vendor: paloaltonetworks

OS: panos

Description:
indeni will trigger an issue if the application package has not been updated according to schedule.

Remediation Steps:
Review possible causes for the update package not being downloaded and installed.

How does this work?
This script uses the Palo Alto Networks API to retrieve the release date of the application package installed on the device.

Why is this important?
Application package release date is important to keep track of the vendor release trains and subsequently the corresponding features.

Without Indeni how would you find this?
Manual tracking by an administrator is usually the only method to know the application package release date.

panos-show-system-info-monitoring

#! META
name: panos-show-system-info-monitoring
description: Fetch system info for monitoring
type: monitoring
monitoring_interval: 5 minute
requires:
    vendor: "paloaltonetworks"
    os.name: "panos"

#! COMMENTS
uptime-milliseconds:
    why: |
        When a monitoring system loses connectivity to a device, it may be difficult for it to determine whether the device restarted, or is simply unreachable. To deal with that, the uptime is tracked. The uptime of a device resetting is a clear indicator of a device restart.
    how: |
        This alert uses the Palo Alto Networks API to retrieve the current uptime (the equivalent of running "show system info" in CLI).
    without-indeni: |
        An administrator will normally find out that a device has restarted when a service outage actually occurs.
    can-with-snmp: true
    can-with-syslog: true
software-eos-date:
    why: |
        Ensuring the software being used is always within the vendor's list of supported versions is critical. Otherwise, during a critical issue, the vendor may decline to provide technical support. Palo Alto Networks posts the list of supported software on their website ( https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary ). indeni tracks that list and updates this script to match.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current software version (the equivalent of running "show system info" in CLI) and based on the software version and the Palo Alto Networks provided information at https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary the correct end of support date is used.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device may be nearing its software end of support and is in need of upgrading.
    can-with-snmp: false
    can-with-syslog: false
hardware-eos-date:
    why: |
        Ensuring the hardware being used is always within the vendor's list of supported models is critical. Otherwise, during a critical issue, the vendor may decline to provide technical support ( https://www.paloaltonetworks.com/services/support/end-of-life-announcements/hardware-end-of-life-dates ). indeni tracks that list and updates this script to match.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current hardware model (the equivalent of running "show system info" in CLI) and based on the model and the Palo Alto Networks provided information at https://www.paloaltonetworks.com/services/support/end-of-life-announcements/hardware-end-of-life-dates the correct end of support date is used.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device may be nearing its end of support and is in need of replacement.
    can-with-snmp: false
    can-with-syslog: false
current-datetime:
    why: |
        The clock of a Palo Alto Networks firewall should always be accurate, as inaccuracies may result in issues with some features, as well as causing a mess in log analysis. Normally, administrators are encouraged to use NTP to keep the clock in sync (and indeni has a script for verifying NTP is working). If NTP is not used, one should still verify that the clock is set correctly.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current date and time (the equivalent of running "show system info" in CLI). indeni then compares the result to its own clock to find possible discrepancies.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device's clock may be off.
    can-with-snmp: false
    can-with-syslog: false
os-version:
    why: |
        Two or more devices which operate as part of a single cluster must be running the same version of software.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software version installed on the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running the same version of software.
    can-with-snmp: false
    can-with-syslog: false
model:
    why: |
        Two or more devices which operate as part of a single cluster must be running on the same hardware.
    how: |
        This script uses the Palo Alto Networks API to retrieve the hardware model of the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running on the same hardware.
    can-with-snmp: false
    can-with-syslog: false
os-name:
    why: |
        Two or more devices which operate as part of a single cluster must be running the same version of software.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software name and version installed on the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running the same version of software.
    can-with-snmp: false
    can-with-syslog: false
panw-panos-panorama-cert-expr:
    why: |
        On April 3rd, 2017, Palo Alto Networks notified all customers that an upgrade to Panorama may be necessary to ensure uninterrupted communications between the Panorama device and the firewalls. Knowing which Panorama installations are affected is important.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software name and version installed on the device.
    without-indeni: |
        An administrator would need to be aware of the issue and manually look at the software version of all Panorama installations.
    can-with-snmp: false
    can-with-syslog: false
panw-installed-app-release-date:
    why: |
        Application package release date is important to keep track of the vendor release trains and subsequently the corresponding features.
    how: |
        This script uses the Palo Alto Networks API to retrieve the release date of the application package installed on the device.
    without-indeni: |
        Manual tracking by an administrator is usually the only method to know the application package release date.
    can-with-snmp: false
    can-with-syslog: false
vendor:
    skip-documentation: true
serial-numbers:
    skip-documentation: true
concurrent-ssl-decryption-limit:
    skip-documentation: true

#! REMOTE::HTTP
url: /api?type=op&cmd=<show><system><info></info></system></show>&key=${api-key}
protocol: HTTPS

#! PARSER::XML
_metrics:
    -
        _tags:
            "im.name":
                _constant: "uptime-milliseconds"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Uptime"
            "im.dstype.displayType":
                _constant: "duration"
        _temp:
            "uptime":
                _text: "/response/result/system/uptime"
        _transform:
            _value.double: |
                {
                    # 230 days, 16:57:34
                    split(temp("uptime"), vals, " ")

                    if (arraylen(vals) == 3    && vals[2] == "days,") {
                        # 230 days, 16:57:34
                        days = vals[1]
                        split(vals[3], timevals, ":")
                        hours = timevals[1]
                        minutes = timevals[2]
                        seconds = timevals[3]

                        uptime = ((days * 3600 * 24) + (hours * 3600) + (minutes * 60) + seconds) * 1000
                        print uptime
                    }

                }
    -
        _tags:
            "im.name":
                _constant: "serial-numbers"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Serial Numbers"
        _value.complex:
            "name":
                _constant: "Device"
            "serial-number":
                _text: "/response/result/system/serial"
        _value: complex-array
    -
        _tags:
            "im.name":
                _constant: "vendor"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _constant: "Palo Alto Networks"
    -
        _tags:
            "im.name":
                _constant: "os-name"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _constant: "PAN-OS"
    -
        _tags:
            "im.name":
                _constant: "os-version"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _text: "/response/result/system/sw-version"
    -
        _tags:
            "im.name":
                _constant: "panw-panos-panorama-cert-expr"
        _temp:
            "swversion":
                _text: "/response/result/system/sw-version"
            "model":
                _text: "/response/result/system/model"
        _transform:
            _value.complex:
                "value": |
                    {
                        if (temp("model") ~ /.*anorama/) {
                            split(temp("swversion"), versionparts, "\\.")
                            if (arraylen(versionparts) == 3) {
                                if (versionparts[1] == "7" && versionparts[2] == "1" && ((versionparts[3] + 0) < 9)) {
                                    print "true"
                                } else if (versionparts[1] == "7" && versionparts[2] == "0" && ((versionparts[3] + 0) < 15)) {
                                    print "true"
                                } else if (versionparts[1] == "6" && versionparts[2] == "1" && ((versionparts[3] + 0) < 17)) {
                                    print "true"
                                } else {
                                    print "false"
                                }
                            } else {
                                print "false"
                            }
                        } else {
                            print "false"
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "model"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _text: "/response/result/system/model"
    -
        _groups:
            "/response/result/system[contains('PA-VM VM-50 PA-200 PA-500 PA-2020 PA-2050 VM-100 VM-200 PA-220 PA-220R VM-1000-HV VM-300 VM-500 VM-700 PA-820 PA-850 PA-3020 PA-3050 PA-3060 PA-3220 PA-3250 PA-3260 PA-4020 PA-4050 PA-4060 PA-5020 PA-5050 PA-5060 PA-5220 PA-5250 PA-5260 PA-5280 PA-7050 PA-7080', model)]":
                _tags:
                    "im.name":
                        _constant: "concurrent-ssl-decryption-limit"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "Maximum Concurrent SSL Decryption Connections"
                    "im.dstype.displayType":
                        _constant: "number"
                _temp:
                    "model":
                        _text: "/response/result/system/model"
                    "vm-license":
                        _text: "/response/result/system/vm-license"
        _transform:
            _value.double: |
                {
                    model = temp("model")
                    #if model is PA-VM, the true model is listed in the vm-license field
                    if (model == "PA-VM") {
                        model = temp("vm-license")
                    }
                    if (model == "VM-50" || model == "PA-200" || model == "PA-500" || model == "PA-2020" || model == "PA-2050") {
                        print 1024
                    } else if (model == "VM-100" || model == "VM-200" || model == "PA-220" || model == "PA-220R") {
                        print 6400
                    } else if (model == "VM-1000-HV" || model == "VM-300") {
                        print 15000
                    } else if (model == "VM-500") {
                        print 50000
                    } else if (model == "VM-700") {
                        print 100000
                    } else if (model == "PA-820") {
                        print 12800
                    } else if (model == "PA-850") {
                        print 19200
                    } else if (model == "PA-3020") {
                        print 7936
                    } else if (model == "PA-3050" || model =="PA-3060") {
                        print 15360
                    } else if (model == "PA-3220") {
                        print 100000
                    } else if (model == "PA-3250") {
                        print 200000
                    } else if (model == "PA-3260") {
                        print 300000
                    } else if (model == "PA-4020") {
                        print 7936
                    } else if (model == "PA-4050" || model == "PA-4060") {
                        print 23808
                    } else if (model == "PA-5020") {
                        print 15872
                    } else if (model == "PA-5050") {
                        print 47616
                    } else if (model == "PA-5060") {
                        print 90112
                    } else if (model == "PA-5220") {
                        print 400000
                    } else if (model == "PA-5250") {
                        print 800000
                    } else if (model == "PA-5260") {
                        print 3200000
                    } else if (model == "PA-5280") {
                        print 6400000
                    } else if (model == "PA-7050") {
                        print 786432
                    } else if (model == "PA-7080") {
                        print 1310720
                    }
                }
    -
        _groups:
            "/response/result/system/sw-version[starts-with(., '5.0.') or starts-with(., '5.1.') or starts-with(., '6.0.') or starts-with(., '6.1.') or starts-with(., '7.0.') or starts-with(., '7.1.') or starts-with(., '8.0.') or starts-with(., '8.1.')]":
                _tags:
                    "im.name":
                        _constant: "software-eos-date"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "End of Support - Software"
                    "im.dstype.displayType":
                        _constant: "date"
                _temp:
                    "sw-version":
                        _text: /response/result/system/sw-version
        _transform:
            _value.double: |
                {
                    # 6.1.2
                    versionstring = temp("sw-version")
                    eos = 0

                    if (match(versionstring, "^5\.0.*")) {
                        eos = date(2016,11,13)
                    } else if (match(versionstring, "^5\.1.*")) {
                        eos = date(2017,5,9)
                    } else if (match(versionstring, "^6\.0.*")) {
                        eos = date(2017,3,19)
                    } else if (match(versionstring, "^6\.1.*")) {
                        eos = date(2018,10,25)
                    } else if (match(versionstring, "^7\.0.*")) {
                        eos = date(2017,12,4)
                    } else if (match(versionstring, "^7\.1.*")) {
                        eos = date(2020,3,29)
                    } else if (match(versionstring, "^8\.0.*")) {
                        eos = date(2019,10,31)
                    } else if (match(versionstring, "^8\.1.*")) {
                        eos = date(2022,3,1)
                    }

                    print eos
                }
    -
        _tags:
            "im.name":
                _constant: "hardware-eos-date"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "End of Support - Hardware"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
                "model":
                    _text: "/response/result/system/model[(starts-with(., 'PA-20') or starts-with(., 'PA-40')) and string-length(.) = 7]"
        _transform:
                _value.double: |
                        {
                            # PA-200
                            modelstring=temp("model")

                            eos=0
                            if (match(modelstring, "PA-20[0-9][0-9]")) {
                                eos=date(2020,4,30)
                            } else if (match(modelstring, "PA-40[0-9][0-9]")) {
                                eos=date(2019,4,30)
                            }

                            if (eos != 0) {
                                print eos
                            } else {
                                print "0"
                            }
                        }
    -
        _tags:
            "im.name":
                _constant: "current-datetime"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Current Time"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
            "time":
                _text: "/response/result/system/time"
        _transform:
                _value.double: |
                    {
                        timestring=temp("time")
                        gsub(/    /, " ", timestring) # We may have double space before the date number
                        split(timestring, vals, " ")
                        if (arraylen(vals) > 4) {
                            split(vals[4], timevals, ":")
                            currenttime = datetime(vals[5], parseMonthThreeLetter(vals[2]), vals[3], timevals[1], timevals[2], timevals[3])
                            print currenttime
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "panw-installed-app-release-date"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Application Packages - Currently Installed Package"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
            "releasedate":
                _text: "/response/result/system/app-release-date"
        _transform:
                _value.double: |
                    {
                        # 2015/03/03    19:53:18
                        releasedatestring=temp("releasedate")
                        gsub(/    /, " ", releasedatestring) # We may have double space before the hour
                        split(releasedatestring, parts, " ")
                        if (arraylen(parts) == 2) {
                            split(parts[1], datevals, "/")
                            split(parts[2], timevals, ":")
                            print datetime(datevals[1], datevals[2], datevals[3], timevals[1], timevals[2], timevals[3])
                        } else {
                            print arraylen(parts)
                        }
                    }

panos-show-system-info-monitoring

#! META
name: panos-show-system-info-monitoring
description: Fetch system info for monitoring
type: monitoring
monitoring_interval: 5 minute
requires:
    vendor: "paloaltonetworks"
    os.name: "panos"

#! COMMENTS
uptime-milliseconds:
    why: |
        When a monitoring system loses connectivity to a device, it may be difficult for it to determine whether the device restarted, or is simply unreachable. To deal with that, the uptime is tracked. The uptime of a device resetting is a clear indicator of a device restart.
    how: |
        This alert uses the Palo Alto Networks API to retrieve the current uptime (the equivalent of running "show system info" in CLI).
    without-indeni: |
        An administrator will normally find out that a device has restarted when a service outage actually occurs.
    can-with-snmp: true
    can-with-syslog: true
software-eos-date:
    why: |
        Ensuring the software being used is always within the vendor's list of supported versions is critical. Otherwise, during a critical issue, the vendor may decline to provide technical support. Palo Alto Networks posts the list of supported software on their website ( https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary ). indeni tracks that list and updates this script to match.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current software version (the equivalent of running "show system info" in CLI) and based on the software version and the Palo Alto Networks provided information at https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary the correct end of support date is used.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device may be nearing its software end of support and is in need of upgrading.
    can-with-snmp: false
    can-with-syslog: false
hardware-eos-date:
    why: |
        Ensuring the hardware being used is always within the vendor's list of supported models is critical. Otherwise, during a critical issue, the vendor may decline to provide technical support ( https://www.paloaltonetworks.com/services/support/end-of-life-announcements/hardware-end-of-life-dates ). indeni tracks that list and updates this script to match.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current hardware model (the equivalent of running "show system info" in CLI) and based on the model and the Palo Alto Networks provided information at https://www.paloaltonetworks.com/services/support/end-of-life-announcements/hardware-end-of-life-dates the correct end of support date is used.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device may be nearing its end of support and is in need of replacement.
    can-with-snmp: false
    can-with-syslog: false
current-datetime:
    why: |
        The clock of a Palo Alto Networks firewall should always be accurate, as inaccuracies may result in issues with some features, as well as causing a mess in log analysis. Normally, administrators are encouraged to use NTP to keep the clock in sync (and indeni has a script for verifying NTP is working). If NTP is not used, one should still verify that the clock is set correctly.
    how: |
        This script uses the Palo Alto Networks API to retrieve the current date and time (the equivalent of running "show system info" in CLI). indeni then compares the result to its own clock to find possible discrepancies.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when a given device's clock may be off.
    can-with-snmp: false
    can-with-syslog: false
os-version:
    why: |
        Two or more devices which operate as part of a single cluster must be running the same version of software.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software version installed on the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running the same version of software.
    can-with-snmp: false
    can-with-syslog: false
model:
    why: |
        Two or more devices which operate as part of a single cluster must be running on the same hardware.
    how: |
        This script uses the Palo Alto Networks API to retrieve the hardware model of the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running on the same hardware.
    can-with-snmp: false
    can-with-syslog: false
os-name:
    why: |
        Two or more devices which operate as part of a single cluster must be running the same version of software.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software name and version installed on the device. indeni then compares the result to the same script run on other members of the same cluster.
    without-indeni: |
        Manual tracking by an administrator is usually the only method for knowing when two devices are not running the same version of software.
    can-with-snmp: false
    can-with-syslog: false
panw-panos-panorama-cert-expr:
    why: |
        On April 3rd, 2017, Palo Alto Networks notified all customers that an upgrade to Panorama may be necessary to ensure uninterrupted communications between the Panorama device and the firewalls. Knowing which Panorama installations are affected is important.
    how: |
        This script uses the Palo Alto Networks API to retrieve the software name and version installed on the device.
    without-indeni: |
        An administrator would need to be aware of the issue and manually look at the software version of all Panorama installations.
    can-with-snmp: false
    can-with-syslog: false
panw-installed-app-release-date:
    why: |
        Application package release date is important to keep track of the vendor release trains and subsequently the corresponding features.
    how: |
        This script uses the Palo Alto Networks API to retrieve the release date of the application package installed on the device.
    without-indeni: |
        Manual tracking by an administrator is usually the only method to know the application package release date.
    can-with-snmp: false
    can-with-syslog: false
vendor:
    skip-documentation: true
serial-numbers:
    skip-documentation: true
concurrent-ssl-decryption-limit:
    skip-documentation: true

#! REMOTE::HTTP
url: /api?type=op&cmd=<show><system><info></info></system></show>&key=${api-key}
protocol: HTTPS

#! PARSER::XML
_metrics:
    -
        _tags:
            "im.name":
                _constant: "uptime-milliseconds"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Uptime"
            "im.dstype.displayType":
                _constant: "duration"
        _temp:
            "uptime":
                _text: "/response/result/system/uptime"
        _transform:
            _value.double: |
                {
                    # 230 days, 16:57:34
                    split(temp("uptime"), vals, " ")

                    if (arraylen(vals) == 3    && vals[2] == "days,") {
                        # 230 days, 16:57:34
                        days = vals[1]
                        split(vals[3], timevals, ":")
                        hours = timevals[1]
                        minutes = timevals[2]
                        seconds = timevals[3]

                        uptime = ((days * 3600 * 24) + (hours * 3600) + (minutes * 60) + seconds) * 1000
                        print uptime
                    }

                }
    -
        _tags:
            "im.name":
                _constant: "serial-numbers"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Serial Numbers"
        _value.complex:
            "name":
                _constant: "Device"
            "serial-number":
                _text: "/response/result/system/serial"
        _value: complex-array
    -
        _tags:
            "im.name":
                _constant: "vendor"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _constant: "Palo Alto Networks"
    -
        _tags:
            "im.name":
                _constant: "os-name"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _constant: "PAN-OS"
    -
        _tags:
            "im.name":
                _constant: "os-version"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _text: "/response/result/system/sw-version"
    -
        _tags:
            "im.name":
                _constant: "panw-panos-panorama-cert-expr"
        _temp:
            "swversion":
                _text: "/response/result/system/sw-version"
            "model":
                _text: "/response/result/system/model"
        _transform:
            _value.complex:
                "value": |
                    {
                        if (temp("model") ~ /.*anorama/) {
                            split(temp("swversion"), versionparts, "\\.")
                            if (arraylen(versionparts) == 3) {
                                if (versionparts[1] == "7" && versionparts[2] == "1" && ((versionparts[3] + 0) < 9)) {
                                    print "true"
                                } else if (versionparts[1] == "7" && versionparts[2] == "0" && ((versionparts[3] + 0) < 15)) {
                                    print "true"
                                } else if (versionparts[1] == "6" && versionparts[2] == "1" && ((versionparts[3] + 0) < 17)) {
                                    print "true"
                                } else {
                                    print "false"
                                }
                            } else {
                                print "false"
                            }
                        } else {
                            print "false"
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "model"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Overview"
        _value.complex:
            "value":
                _text: "/response/result/system/model"
    -
        _groups:
            "/response/result/system[contains('PA-VM VM-50 PA-200 PA-500 PA-2020 PA-2050 VM-100 VM-200 PA-220 PA-220R VM-1000-HV VM-300 VM-500 VM-700 PA-820 PA-850 PA-3020 PA-3050 PA-3060 PA-3220 PA-3250 PA-3260 PA-4020 PA-4050 PA-4060 PA-5020 PA-5050 PA-5060 PA-5220 PA-5250 PA-5260 PA-5280 PA-7050 PA-7080', model)]":
                _tags:
                    "im.name":
                        _constant: "concurrent-ssl-decryption-limit"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "Maximum Concurrent SSL Decryption Connections"
                    "im.dstype.displayType":
                        _constant: "number"
                _temp:
                    "model":
                        _text: "/response/result/system/model"
                    "vm-license":
                        _text: "/response/result/system/vm-license"
        _transform:
            _value.double: |
                {
                    model = temp("model")
                    #if model is PA-VM, the true model is listed in the vm-license field
                    if (model == "PA-VM") {
                        model = temp("vm-license")
                    }
                    if (model == "VM-50" || model == "PA-200" || model == "PA-500" || model == "PA-2020" || model == "PA-2050") {
                        print 1024
                    } else if (model == "VM-100" || model == "VM-200" || model == "PA-220" || model == "PA-220R") {
                        print 6400
                    } else if (model == "VM-1000-HV" || model == "VM-300") {
                        print 15000
                    } else if (model == "VM-500") {
                        print 50000
                    } else if (model == "VM-700") {
                        print 100000
                    } else if (model == "PA-820") {
                        print 12800
                    } else if (model == "PA-850") {
                        print 19200
                    } else if (model == "PA-3020") {
                        print 7936
                    } else if (model == "PA-3050" || model =="PA-3060") {
                        print 15360
                    } else if (model == "PA-3220") {
                        print 100000
                    } else if (model == "PA-3250") {
                        print 200000
                    } else if (model == "PA-3260") {
                        print 300000
                    } else if (model == "PA-4020") {
                        print 7936
                    } else if (model == "PA-4050" || model == "PA-4060") {
                        print 23808
                    } else if (model == "PA-5020") {
                        print 15872
                    } else if (model == "PA-5050") {
                        print 47616
                    } else if (model == "PA-5060") {
                        print 90112
                    } else if (model == "PA-5220") {
                        print 400000
                    } else if (model == "PA-5250") {
                        print 800000
                    } else if (model == "PA-5260") {
                        print 3200000
                    } else if (model == "PA-5280") {
                        print 6400000
                    } else if (model == "PA-7050") {
                        print 786432
                    } else if (model == "PA-7080") {
                        print 1310720
                    }
                }
    -
        _groups:
            "/response/result/system/sw-version[starts-with(., '5.0.') or starts-with(., '5.1.') or starts-with(., '6.0.') or starts-with(., '6.1.') or starts-with(., '7.0.') or starts-with(., '7.1.') or starts-with(., '8.0.') or starts-with(., '8.1.')]":
                _tags:
                    "im.name":
                        _constant: "software-eos-date"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "End of Support - Software"
                    "im.dstype.displayType":
                        _constant: "date"
                _temp:
                    "sw-version":
                        _text: /response/result/system/sw-version
        _transform:
            _value.double: |
                {
                    # 6.1.2
                    versionstring = temp("sw-version")
                    eos = 0

                    if (match(versionstring, "^5\.0.*")) {
                        eos = date(2016,11,13)
                    } else if (match(versionstring, "^5\.1.*")) {
                        eos = date(2017,5,9)
                    } else if (match(versionstring, "^6\.0.*")) {
                        eos = date(2017,3,19)
                    } else if (match(versionstring, "^6\.1.*")) {
                        eos = date(2018,10,25)
                    } else if (match(versionstring, "^7\.0.*")) {
                        eos = date(2017,12,4)
                    } else if (match(versionstring, "^7\.1.*")) {
                        eos = date(2020,3,29)
                    } else if (match(versionstring, "^8\.0.*")) {
                        eos = date(2019,10,31)
                    } else if (match(versionstring, "^8\.1.*")) {
                        eos = date(2022,3,1)
                    }

                    print eos
                }
    -
        _tags:
            "im.name":
                _constant: "hardware-eos-date"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "End of Support - Hardware"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
                "model":
                    _text: "/response/result/system/model[(starts-with(., 'PA-20') or starts-with(., 'PA-40')) and string-length(.) = 7]"
        _transform:
                _value.double: |
                        {
                            # PA-200
                            modelstring=temp("model")

                            eos=0
                            if (match(modelstring, "PA-20[0-9][0-9]")) {
                                eos=date(2020,4,30)
                            } else if (match(modelstring, "PA-40[0-9][0-9]")) {
                                eos=date(2019,4,30)
                            }

                            if (eos != 0) {
                                print eos
                            } else {
                                print "0"
                            }
                        }
    -
        _tags:
            "im.name":
                _constant: "current-datetime"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Current Time"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
            "time":
                _text: "/response/result/system/time"
        _transform:
                _value.double: |
                    {
                        timestring=temp("time")
                        gsub(/    /, " ", timestring) # We may have double space before the date number
                        split(timestring, vals, " ")
                        if (arraylen(vals) > 4) {
                            split(vals[4], timevals, ":")
                            currenttime = datetime(vals[5], parseMonthThreeLetter(vals[2]), vals[3], timevals[1], timevals[2], timevals[3])
                            print currenttime
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "panw-installed-app-release-date"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Application Packages - Currently Installed Package"
            "im.dstype.displayType":
                _constant: "date"
        _temp:
            "releasedate":
                _text: "/response/result/system/app-release-date"
        _transform:
                _value.double: |
                    {
                        # 2015/03/03    19:53:18
                        releasedatestring=temp("releasedate")
                        gsub(/    /, " ", releasedatestring) # We may have double space before the hour
                        split(releasedatestring, parts, " ")
                        if (arraylen(parts) == 2) {
                            split(parts[1], datevals, "/")
                            split(parts[2], timevals, ":")
                            print datetime(datevals[1], datevals[2], datevals[3], timevals[1], timevals[2], timevals[3])
                        } else {
                            print arraylen(parts)
                        }
                    }

panos-show_config_running-monitoring-xml

#! META
name: panos-show_config_running-monitoring-xml
description: Fetch the running config (xml)
type: monitoring
monitoring_interval: 60 minute
requires:
    vendor: paloaltonetworks
    os.name: panos

#! COMMENTS
certificate-expiration:
    why: |
        Palo Alto Networks firewalls use certificate for a variety of different purposes. One purpose, for example, is inbound SSL inspection. If the certificate used by the firewall expires, certain services may be unavailable to external users.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration, reviews the certificates saved and retrieves their subject and expiration date.
    without-indeni: |
        An administrator may manually review the certificates and their expiration dates, by looking at the web interface.
    can-with-snmp: true
    can-with-syslog: true
timezone:
    why: |
        Most configurations in Palo Alto Networks firewalls are synchronized across cluster members. Some are not, the timezone is one of them. It is important to verify that the timezone is the same on all cluster members to avoid confusion or issues.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the timezone from there.
    without-indeni: |
        An administrator may write a script to pull this data from cluster members and compare it.
    can-with-snmp: false
    can-with-syslog: false
domain:
    why: |
        Most configurations in Palo Alto Networks firewalls are synchronized across cluster members. Some are not, the domain name is one of them. It is important to verify that the domain name is the same on all cluster members to avoid confusion or issues.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the timezone from there.
    without-indeni: |
        An administrator may write a script to pull this data from cluster members and compare it.
    can-with-snmp: false
    can-with-syslog: false
login-banner:
    why: |
        Most configurations in Palo Alto Networks firewalls are synchronized across cluster members. Some are not, the login banner is one of them. It is important to verify that the login banner is the same on all cluster members to avoid confusion or issues.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the timezone from there.
    without-indeni: |
        An administrator may write a script to pull this data from cluster members and compare it.
    can-with-snmp: false
    can-with-syslog: false
syslog-servers:
    why: |
        Tracking the currently configured Syslog servers on all devices is important to ensure consistent logging.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured Syslog servers from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
radius-servers:
    why: |
        Tracking the currently configured RADIUS servers on all devices is important to ensure consistent authentication and access.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured RADIUS servers from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
dns-servers:
    why: |
        Tracking the currently configured DNS servers on all devices is important to ensure consistent name resolution.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured DNS servers from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
ntp-servers:
    why: |
        Tracking the currently configured NTP servers on all devices is important to ensure consistent time sync.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured NTP servers from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
unencrypted-snmp-configured:
    why: |
        SNMPv2c is an unsecure protocol and should not be used. Users should prefer the more secure SNMPv3.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured services from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
telnet-enabled:
    why: |
        Telnet is an unsecure protocol and should not be used. Users may enable telnet unintentionally and should be alerted if they do so.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured services from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
http-server-enabled:
    why: |
        HTTP is an unsecure protocol and should not be used. Users may enable HTTP unintentionally and should be alerted if they do so.
    how: |
        This script pulls the Palo Alto Networks firewall's active configuration and extracts the configured services from there.
    without-indeni: |
        An administrator may write a script to pull this data from devices and compare against a gold configuration.
    can-with-snmp: false
    can-with-syslog: false
license-elements-used:
    skip-documentation: true
app-update-acceptable-lag:
    skip-documentation: true

#! REMOTE::HTTP
url: /api?type=op&cmd=<show><config><running></running></config></show>&key=${api-key}
protocol: HTTPS

#! PARSER::XML
_vars:
    root: /response/result/config
_metrics:
    -
        _groups:
            ${root}/shared/certificate/entry:
                _value.double:
                    _text: "expiry-epoch"
                _tags:
                    name:
                        _text: "subject"
                    "im.name":
                        _constant: "certificate-expiration"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "Certificate Expiration"
                    "im.dstype.displayType":
                        _constant: "date"
                    "im.identity-tags":
                        _constant: "name"
    -
        _value.complex:
            value:
                _text: "${root}/devices/entry/deviceconfig/system/timezone"
        _tags:
            "im.name":
                _constant: "timezone"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Timezone"
    -
        _value.complex:
            value:
                _text: "${root}/devices/entry/deviceconfig/system/domain"
        _tags:
            "im.name":
                _constant: "domain"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Domain"
    -
        _value.complex:
            value:
                _text: "${root}/devices/entry/deviceconfig/system/login-banner"
        _tags:
            "im.name":
                _constant: "login-banner"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Login Banner"
    -
        _tags:
            "im.name":
                _constant: "app-update-acceptable-lag"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Application Packages - Acceptable Lag"
            "im.dstype.displayType":
                _constant: "duration"
        _temp:
            isweekly:
                _count: "${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring/weekly"
            ishourly:
                _count: "${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring/hourly"
            isdaily:
                _count: "${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring/daily"
            threshold:
                # This is a hack. The threshold may, or may not exist.
                # If we were to refer to it directly and it didn't exist, the entire metric
                # would have been aborted. So instead, we "name" the text of it, as well as
                # another, related node. If the threshold exists, we'll be getting its value.
                # If it doesn't, we'll get "recurring" (the name of the node in the second path)
                _name: "${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring/threshold/text() | ${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring[not(threshold)]"
        _transform:
            _value.double: |
                    {
                        # The acceptable lag depends on the kind of schedule used
                        acceptablelag=0
                        if (temp("isweekly") == "1") {
                            acceptablelag=8*24*3600
                        } else if (temp("ishourly") == "1") {
                            acceptablelag=2*3600
                        } else if (temp("isdaily") == "1") {
                            acceptablelag=47*3600
                        }

                        # Add threshold
                        if (temp("threshold") != "recurring") {
                            acceptablelag = acceptablelag + (temp("threshold") * 3600)
                        }

                        print acceptablelag
                    }
    -
        _tags:
            "im.name":
                _constant: "panw-app-update-action"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Application Packages - Update Action"
            "im.dstype.displayType":
                _constant: "string"
        _value.complex:
            value:
                _text: "${root}/devices/entry/deviceconfig/system/update-schedule/threats/recurring/*/action"
    -
        _groups:
            "${root}//syslog/entry/server/entry":
                _value.complex:
                    "host":
                        _text: "server"
                    "severity":
                        _text: "facility"
                _tags:
                    "im.name":
                        _constant: "syslog-servers"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "Syslog Servers"
        _value: complex-array
    -
        _groups:
            "${root}//radius/entry/server/entry":
                _value.complex:
                    "host":
                        _text: "ip-address"
                    "port":
                        _text: "port"
                _tags:
                    "im.name":
                        _constant: "radius-servers"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "RADIUS Servers"
        _value: complex-array
    -
        _groups:
            "/response/result/config/devices/entry/deviceconfig/system/dns-setting/servers/*":
                _value.complex:
                    "ipaddress":
                        _text: .
                _tags:
                    "im.name":
                        _constant: "dns-servers"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "DNS Servers"
        _value: complex-array
    -
        _groups:
            "/response/result/config/devices/entry/deviceconfig/system/ntp-servers/*/ntp-server-address":
                _value.complex:
                    "ipaddress":
                        _text: .
                _tags:
                    "im.name":
                        _constant: "ntp-servers"
                    "live-config":
                        _constant: "true"
                    "display-name":
                        _constant: "NTP Servers"
        _value: complex-array
    -
        _value.double:
            _count: /response/result/config/devices/entry/vsys/entry
        _tags:
            "name":
                _constant: "vsys"
            "im.name":
                _constant: "license-elements-used"
            "live-config":
                _constant: "true"
            "display-name":
                _constant: "Licenses - Usage"
            "im.dstype.displayType":
                _constant: "number"
            "im.identity-tags":
                _constant: "name"
    -
        _tags:
            "im.name":
                _constant: "unencrypted-snmp-configured"
        _temp:
            hasSnmpV2c:
                _count: "/response/result/config/devices/entry/deviceconfig/system/snmp-setting/access-setting/version/v2c"
        _transform:
            _value.complex:
                value: |
                    {
                        if (temp("hasSnmpV2c") == "1") {
                            print "true"
                        } else {
                            print "false"
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "telnet-enabled"
        _temp:
            hasTelnetAtNo:
                _count: "${root}/devices/entry/deviceconfig/system/service/disable-telnet[text() = 'no']"
        _transform:
            _value.complex:
                value: |
                    {
                        if (temp("hasTelnetAtNo") == "1") {
                            print "true"
                        } else {
                            print "false"
                        }
                    }
    -
        _tags:
            "im.name":
                _constant: "http-server-enabled"
        _temp:
            hasHttpAtNo:
                _count: "${root}/devices/entry/deviceconfig/system/service/disable-http[text() = 'no']"
        _transform:
            _value.complex:
                value: |
                    {
                        if (temp("hasHttpAtNo") == "1") {
                            print "true"
                        } else {
                            print "false"
                        }
                    }

panw_app_lag_check

package com.indeni.server.rules.library

import com.indeni.apidata.time.TimeSpan
import com.indeni.apidata.time.TimeSpan.TimePeriod
import com.indeni.ruleengine.expressions.conditions.{And, LesserThan, Or, Equals => RuleEquals}
import com.indeni.ruleengine.expressions.core.{StatusTreeExpression, _}
import com.indeni.ruleengine.expressions.data._
import com.indeni.ruleengine.expressions.math.MinusExpression
import com.indeni.server.common.data.conditions.True
import com.indeni.server.rules._
import com.indeni.server.rules.library.core.PerDeviceRule
import com.indeni.server.sensor.models.managementprocess.alerts.dto.AlertSeverity

case class PanwAppPackageNotUpdatedRule() extends PerDeviceRule with RuleHelper {

  override val metadata: RuleMetadata = RuleMetadata
    .builder(
      "panw_app_lag_check",
      "Palo Alto Networks Firewalls: Application package not up to date",
      "indeni will trigger an issue if the application package has not been updated according to schedule.",
      AlertSeverity.WARN
    )
    .build()

  override def expressionTree(context: RuleContext): StatusTreeExpression = {
    val currentTime = TimeSeriesExpression[Double]("current-datetime").last.toTimeSpan(TimePeriod.SECOND)
    val acceptableLag = TimeSeriesExpression[Double]("app-update-acceptable-lag").last.toTimeSpan(TimePeriod.SECOND)
    val installedPackageDate =
      TimeSeriesExpression[Double]("panw-installed-app-release-date").last.toTimeSpan(TimePeriod.SECOND)
    val externalServiceError = TimeSeriesExpression[Double]("external-service-error").last
    val contentUpdateState = SnapshotExpression("content-update-state").asSingle().mostRecent().value().noneable

    StatusTreeExpression(
      // Which objects to pull (normally, devices)
      SelectTagsExpression(context.metaDao, Set(DeviceKey), True),
      // What constitutes an issue
      Or(
        StatusTreeExpression(
          // The time-series we check the test condition against:
          SelectTimeSeriesExpression[Double](context.tsDao, Set("external-service-error"), denseOnly = false),
          // The condition which, if true, we have an issue. Checked against the time-series we've collected
          externalServiceError.is(1)
          // The Alert Item to add for this specific item
        ).withSecondaryInfo(
            ConstantExpression("Error retrieving version number in cloud"),
            EMPTY_STRING,
            "Issues"
          )
          .asCondition(),
        StatusTreeExpression(
          // The time-series we check the test condition against:
          SelectTimeSeriesExpression[Double](context.tsDao,
                                             Set("panw-installed-app-release-date",
                                                 "current-datetime",
                                                 "app-update-acceptable-lag"),
                                             denseOnly = false),
          // The condition which, if true, we have an issue. Checked against the time-series we've collected
          And(
            LesserThan(acceptableLag, MinusExpression[TimeSpan](currentTime, installedPackageDate)),
            StatusTreeExpression(
              SelectSnapshotsExpression(context.snapshotsDao, Set("content-update-state")).single(),
              RuleEquals(RuleHelper.createComplexStringConstantExpression("false"), contentUpdateState)
            ).withoutInfo().asCondition()
          )
          // The Alert Item to add for this specific item
        ).withSecondaryInfo(
            ConstantExpression("Application package not up to date"),
            scopableStringFormatExpression(
              "The current app update package's release date is %s. This indicates the update schedule is not operating correctly.",
              timeSpanToDateExpression(installedPackageDate)
            ),
            "Issues"
          )
          .asCondition()
      )
    ).withRootInfo(
      getHeadline(),
      scopableStringFormatExpression("Application package not up to date"),
      ConstantExpression(
        """|Run the command 'request content upgrade check or request anti-virus upgrade check’.
          |
          |If you do not receive an error you may request an upgrade manually by running either ‘request content upgrade install version latest’ or ‘request anti-virus upgrade install version latest’.
          |
          |Review possible causes for the update package not being checked successfully.
          |1. Try to ping from the firewall "ping host updates.paloaltonetworks.com". If fails DNS resolution check configured DNS servers.
          |2. Check the source interface for Palo Alto Networks Services and routes for that interface to the Internet.
          |
          |Review possible root causes for the update package not being updated successfully. Some things that can occur:
          |1. Error communicating with the cloud.
          |2. Failed to install after download.
          |3. Corrupt content/av database that needs repair.
          |4. Less mp-log ms.log on the firewall CLI to look for error messages
          |
          |Check the Indeni Crowd https://community.indeni.com and https://live.paloaltonetworks.com for possible reasons of dynamic update failures (content or anti-virus).
        """.stripMargin)
    )
  }
}