Exemple #1
0
    def run(self):
        alerts = []
        for vol in Volume.objects.filter(vol_fstype='ZFS'):
            if vol.is_upgraded is not True:
                alerts.append(Alert(
                    Alert.WARN, _(
                        'New feature flags are available for volume %s. Refer '
                        'to the "Upgrading a ZFS Pool" section of the User '
                        'Guide for instructions.'
                    ) % vol.vol_name,
                ))

        proc = subprocess.Popen(
            "zfs upgrade | grep FILESYSTEM",
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        output = proc.communicate()[0].strip(' ').strip('\n')
        if output:
            alerts.append(Alert(Alert.WARN, _(
                'ZFS filesystem version is out of date. Consider upgrading'
                ' using "zfs upgrade" command line.'
            )))

        return alerts
Exemple #2
0
    def run(self):
        if not os.path.exists(LICENSE_FILE):
            return None
        with open(LICENSE_FILE, 'rb') as f:
            data = f.read()
        try:
            license = License.load(data)
        except:
            return [Alert(
                Alert.CRIT,
                _('Unable to decode %s license') % get_sw_name(),
            )]

        end_date = license.contract_end
        if end_date < datetime.now().date():
            return [Alert(
                Alert.CRIT,
                _('Your %s license has expired') % get_sw_name(),
            )]
        elif end_date - timedelta(days=30) < datetime.now().date():
            return [Alert(
                Alert.WARN, _(
                    'Your %(sw_name)s license is going to expire in %(date)s'
                ) % {
                    'sw_name': get_sw_name(),
                    'date': end_date,
                }
            )]
    def run(self):
        alerts = []
        if os.path.exists('/tmp/alert_invalid_ssl_nginx'):
            msg = 'HTTP SSL certificate is not valid, failling back to HTTP'
            try:
                open('/tmp/alert_invalid_ssl_nginx').read().split()[0]
                msg = 'FreeNAS does not support certificates with keys shorter than 1024 bits. HTTPS will not be enabled until a certificate having at least 1024 bit keylength is provided'
            except IndexError:
                pass
            alerts.append(Alert(Alert.WARN, msg))
        for cert_name in glob.glob("/var/tmp/alert_invalidcert_*"):
            alerts.append(
                Alert(
                    Alert.WARN,
                    _('The Certificate: %(cert_name)s is either malformed '
                      'or invalid and cannot be used for any services. This '
                      'Alert will remain here until the certificate is deleted'
                      ) % {'cert_name': cert_name.split('_', 2)[-1]}))

        for CA_name in glob.glob("/var/tmp/alert_invalidCA_*"):
            alerts.append(
                Alert(
                    Alert.WARN,
                    _('The Certificate Authority(CA): %(CA_name)s is either '
                      'malformed or invalid and cannot be used for any services.'
                      ' This Alert will remain here until the CA is deleted') %
                    {'CA_name': CA_name.split('_', 2)[-1]}))
        return alerts
Exemple #4
0
    def run(self):
        if not Volume.objects.all().exists():
            return None
        if (
            hasattr(notifier, 'failover_status') and
            notifier().failover_status() == 'BACKUP'
        ):
            return None
        systemdataset, basename = notifier().system_dataset_settings()
        if not systemdataset.sys_pool:
            return [
                Alert(
                    Alert.WARN,
                    "No system pool configured, please configure one in "
                    "Settings->System Dataset->Pool"
                ),
            ]

        if os.path.exists('/var/db/samba4/.alert_cant_migrate'):
            return [
                Alert(
                    Alert.WARN,
                    "Multiple legacy samba4 datasets detected. Auto-migration "
                    "to /mnt/%s/.system/samba4 cannot be done. Please perform "
                    "this step manually and then delete the now-obsolete "
                    "samba4 datasets and /var/db/samba4/.alert_cant_migrate"
                    % systemdataset.sys_pool
                ),
            ]
Exemple #5
0
    def run(self):
        alerts = []
        mps = defaultdict(dict)
        for o in sysctl.filter('dev.mps'):
            mibs = o.name.split('.', 3)
            if len(mibs) < 4:
                continue

            number, mib = mibs[2:4]

            try:
                major = int(o.value.split('.', 1)[0])
                mps[number][mib] = major
            except:
                continue

        for number, mibs in list(mps.items()):
            firmware = mibs.get('firmware_version')
            driver = mibs.get('driver_version')
            try:
                # Broadcom added a new one for us, an allowed combo is p20 firmware and v21 driver
                # https://bugs.freenas.org/issues/16649
                if ((int(firmware) != int(driver))
                        and not (int(firmware) == 20 and int(driver) == 21)):
                    alerts.append(
                        Alert(
                            Alert.WARN,
                            _('Firmware version %(fwversion)s does not match driver '
                              'version %(drversion)s for /dev/mps%(mps)s. Please '
                              'flash controller to P%(drversion)s IT firmware.'
                              ) % {
                                  'fwversion': firmware,
                                  'drversion': driver,
                                  'mps': number,
                              }))
            except ValueError:
                # cast returned Cthulhu
                # This shouldn't ever happen but as a fallback try the old method
                if ((firmware != driver)
                        and not (firmware.startswith("20")
                                 and driver.startswith("21"))):
                    alerts.append(
                        Alert(
                            Alert.WARN,
                            _('Firmware version %(fwversion)s does not match driver '
                              'version %(drversion)s for /dev/mps%(mps)s') % {
                                  'fwversion': firmware,
                                  'drversion': driver,
                                  'mps': number,
                              }))

        return alerts
 def on_volume_status_not_healthy(self, status, message):
     if message:
         return Alert(
             Alert.WARN,
             _('The boot volume status is %(status)s:'
               ' %(message)s') % {
                   'status': status,
                   'message': message,
               })
     else:
         return Alert(
             Alert.WARN,
             _('The boot volume status is %(status)s') % {
                 'status': status,
             })
Exemple #7
0
    def run(self):
        alerts = []

        if not os.path.exists(SMART_FILE):
            return alerts

        lock = LockFile(SMART_FILE)

        while not lock.i_am_locking():
            try:
                lock.acquire(timeout=5)
            except LockTimeout:
                return alerts

        with open(SMART_FILE, 'rb') as f:
            try:
                data = pickle.loads(f.read())
            except:
                data = {}

        msg = ''
        for msgs in data.itervalues():
            if not msgs:
                continue
            msg += '<br />\n'.join(msgs)

        if msg:
            alerts.append(Alert(Alert.CRIT, msg))

        lock.release()

        return alerts
Exemple #8
0
    def run(self):
        alerts = []
        systemname = pipeopen(
            "/usr/local/sbin/dmidecode -s system-product-name").communicate(
            )[0].strip()
        boardname = pipeopen(
            "/usr/local/sbin/dmidecode -s baseboard-product-name").communicate(
            )[0].strip()
        if 'freenas' in systemname.lower() and boardname == 'C2750D4I':
            mcinfo = pipeopen(
                "/usr/local/bin/ipmitool mc info").communicate()[0]
            reg = re.search(r'Firmware Revision.*: (\S+)', mcinfo, flags=re.M)
            if not reg:
                return alerts
            fwver = reg.group(1)
            try:
                fwver = [int(i) for i in fwver.split('.')]
            except ValueError:
                log.warn(
                    'Failed to parse BMC firmware version: {}'.format(fwver))
                return alerts

            if len(fwver) < 2 or not (fwver[0] == 0 and fwver[1] < 30):
                return alerts

            alerts.append(
                Alert(
                    Alert.CRIT,
                    _('FreeNAS Mini Critical IPMI Firmware Update - Your '
                      'Mini has an available IPMI firmware update, please '
                      'click <a href="%s" target="_blank">here</a> for '
                      'installation instructions') %
                    'https://support.ixsystems.com/index.php?/Knowledgebase/Article/View/287',
                ))
        return alerts
Exemple #9
0
    def run(self):
        alerts = []

        if not os.path.exists(COLLECTD_FILE):
            return alerts

        lock = LockFile(COLLECTD_FILE)

        while not lock.i_am_locking():
            try:
                lock.acquire(timeout=5)
            except LockTimeout:
                return alerts

        with open(COLLECTD_FILE, 'rb') as f:
            try:
                data = pickle.loads(f.read())
            except:
                data = {}

        lock.release()

        for k, v in list(data.items()):
            if v['Severity'] == 'WARNING':
                l = Alert.WARN
            else:
                l = Alert.CRIT
            if k == 'ctl-ha/disk_octets':
                msg = "CTL HA link is actively used, check initiators connectivity"
            else:
                msg = k
            alerts.append(Alert(l, msg))

        return alerts
Exemple #10
0
    def run(self):
        alerts = []
        mpr = defaultdict(dict)
        for o in sysctl.filter('dev.mpr'):
            mibs = o.name.split('.', 3)
            if len(mibs) < 4:
                continue

            number, mib = mibs[2:4]

            try:
                major = int(o.value.split('.', 1)[0])
                mpr[number][mib] = major
            except:
                continue

        for number, mibs in mpr.items():
            firmware = mibs.get('firmware_version')
            driver = mibs.get('driver_version')
            if firmware != driver:
                alerts.append(
                    Alert(
                        Alert.WARN,
                        _('Firmware version %(fwversion)s does not match driver '
                          'version %(drversion)s for /dev/mpr%(mpr)s') % {
                              'fwversion': firmware,
                              'drversion': driver,
                              'mpr': number,
                          }))

        return alerts
Exemple #11
0
    def run(self):
        alerts = []

        if not os.path.exists(SMART_FILE):
            return alerts

        lock = LockFile(SMART_FILE)

        while not lock.i_am_locking():
            try:
                lock.acquire(timeout=5)
            except LockTimeout:
                return alerts

        with open(SMART_FILE, 'rb') as f:
            try:
                data = pickle.loads(f.read())
            except:
                data = {}

        for msgs in data.itervalues():
            if not msgs:
                continue
            for msg in msgs:
                if msg is None:
                    continue
                alerts.append(Alert(Alert.CRIT, msg, hardware=True))

        lock.release()

        return alerts
Exemple #12
0
    def run(self):
        alerts = []
        try:
            update = Update.objects.order_by('-id')[0]
        except IndexError:
            update = Update.objects.create()

        path = notifier().system_dataset_path()
        if not path:
            return None
        try:
            check = CheckForUpdates(train=update.get_train(), cache_dir=path)
        except:
            check = None
        if check:
            alerts.append(
                Alert(
                    Alert.OK,
                    _(
                        'There is a new update available! Apply it in System '
                        '-> Update tab.'
                    ),
                )
            )
        return alerts
Exemple #13
0
    def run(self):
        alerts = []
        try:
            update = Update.objects.order_by('-id')[0]
        except IndexError:
            update = Update.objects.create()

        path = notifier().get_update_location()
        if not path:
            return None
        try:
            updates = PendingUpdates(path)
        except:
            updates = None

        if updates:
            alerts.append(
                Alert(
                    Alert.OK,
                    _(
                        'There is a new update available! Apply it in System '
                        '-> Update tab.'
                    ),
                )
            )
        return alerts
    def run(self):

        alerts = []

        if (services.objects.get(srv_service='smartd').srv_enable):
            # sysctl kern.vm_guest will return a hypervisor name, or the string "none" if FreeNAS is running on bare iron.
            p0 = subprocess.Popen(["/sbin/sysctl", "-n", "kern.vm_guest"],
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  encoding='utf8')
            status = p0.communicate()[0].strip()
            # This really isn't confused with python None
            if status != "none":
                # We got something other than "none", maybe "vmware", "xen", "vbox".  Regardless, smartd not running
                # in these environments isn't a huge deal.  So we'll skip alerting.
                return None
            if hasattr(notifier, 'failover_status'
                       ) and notifier().failover_status() != 'MASTER':
                return None
            p1 = subprocess.Popen(["/usr/sbin/service", "smartd", "status"],
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  encoding='utf8')
            status = p1.communicate()[0]
            if p1.returncode == 1:
                alerts.append(Alert(Alert.WARN, status))
            else:
                return None
        else:
            return None

        return alerts
Exemple #15
0
 def on_volume_status_not_healthy(self, state, status):
     return Alert(
         Alert.CRIT,
         _('The boot volume state is %(state)s: %(status)s') % {
             'state': state,
             'status': status,
         })
Exemple #16
0
    def run(self):
        alerts = []
        mps = defaultdict(dict)
        for o in sysctl.filter('dev.mps'):
            mibs = o.name.split('.', 3)
            if len(mibs) < 4:
                continue

            number, mib = mibs[2:4]

            try:
                major = int(o.value.split('.', 1)[0])
                mps[number][mib] = major
            except:
                continue

        for number, mibs in mps.items():
            firmware = mibs.get('firmware_version')
            driver = mibs.get('driver_version')
            try:
                if int(firmware) != int(driver):
                    alerts.append(
                        Alert(
                            Alert.WARN,
                            _('Firmware version %(fwversion)s does not match driver '
                              'version %(drversion)s for /dev/mps%(mps)s. Please '
                              'flash controller to P%(drversion)s IT firmware.'
                              ) % {
                                  'fwversion': firmware,
                                  'drversion': driver,
                                  'mps': number,
                              }))
            except ValueError:
                # cast returned cthulu
                # This shouldn't ever happen but as a fallback try the old method
                if firmware != driver:
                    alerts.append(
                        Alert(
                            Alert.WARN,
                            _('Firmware version %(fwversion)s does not match driver '
                              'version %(drversion)s for /dev/mps%(mps)s') % {
                                  'fwversion': firmware,
                                  'drversion': driver,
                                  'mps': number,
                              }))

        return alerts
Exemple #17
0
 def on_volume_status_not_healthy(self, vol, state, status):
     return Alert(Alert.CRIT, _(
         'The volume %(volume)s state is %(state)s: %(status)s'
     ) % {
         'volume': vol,
         'state': state,
         'status': status,
     })
Exemple #18
0
 def run(self):
     if os.path.exists('/tmp/alert_invalid_ssl_nginx'):
         return [
             Alert(
                 Alert.WARN,
                 'HTTP SSL certificate is not valid, failling back to HTTP'
             ),
         ]
    def run(self):

        alerts = []

        if os.path.exists('/tmp/.ldap_status_alert'):
            alerts.append(Alert(Alert.WARN, "LDAP did not bind to the domain"))

        return alerts
Exemple #20
0
 def run(self):
     alerts = []
     if os.path.exists(GELI_REKEY_FAILED):
         alerts.append(Alert(Alert.CRIT, _(
             'Encrypted volume failed to rekey some disks. Please make '
             'sure you have working recovery keys, check logs files and '
             'correct the error as it may result to data loss.'
         ), hardware=True))
     return alerts
 def run(self):
     if os.path.exists('/tmp/.nfsbindip_notfound'):
         return [
             Alert(
                 Alert.WARN,
                 _('NFS services could not bind specific IPs, using wildcard'
                   ),
             )
         ]
    def run(self):

        alerts = []

        if os.path.exists('/tmp/.adalert'):
            alerts.append(
                Alert(Alert.WARN,
                      "ActiveDirectory did not bind to the domain"))

        return alerts
Exemple #23
0
 def run(self):
     alerts = []
     if os.path.exists('/data/update.failed'):
         alerts.append(
             Alert(
                 Alert.CRIT,
                 _('Update failed. Check /data/update.failed for further '
                   'details.'),
             ))
     return alerts
Exemple #24
0
    def run(self):
        alerts = []
        for iface in netif.list_interfaces().values():
            if not isinstance(iface, netif.LaggInterface):
                continue
            active = []
            inactive = []
            for name, flags in iface.ports:
                if netif.LaggPortFlags.ACTIVE not in flags:
                    inactive.append(name)
                else:
                    active.append(name)

            # ports that are not ACTIVE and LACP
            if inactive and iface.protocol == netif.AggregationProtocol.LACP:
                # Only alert if this has happened more than twice, see #24160
                self.__count[iface.name] += 1
                if self.__count[iface.name] > 2:
                    alerts.append(
                        Alert(
                            Alert.CRIT,
                            _('These ports are not ACTIVE on LAGG interface %(name)s: %(ports)s. Please check cabling and switch.'
                              ) % {
                                  'name': iface.name,
                                  'ports': ', '.join(inactive)
                              },
                        ))
            # For FAILOVER protocol we should have one ACTIVE port
            elif len(
                    active
            ) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER:
                # Only alert if this has happened more than twice, see #24160
                self.__count[iface.name] += 1
                if self.__count[iface.name] > 2:
                    alerts.append(
                        Alert(
                            Alert.CRIT,
                            _('There are no ACTIVE ports on LAGG interface %(name)s. Please check cabling and switch.'
                              ) % {'name': iface.name},
                        ))
            else:
                self.__count[iface.name] = 0
        return alerts
Exemple #25
0
 def run(self):
     if os.path.exists('/tmp/alert_invalid_ssl_nginx'):
         msg = 'HTTP SSL certificate is not valid, failling back to HTTP'
         try:
             a = open('/tmp/alert_invalid_ssl_nginx').read().split()[0]
             msg = 'FreeNAS does not support certificates with keys shorter than 1024 bits. HTTPS will not be enabled until a certificate having at least 1024 bit keylength is provided'
         except IndexError:
             pass
         return [
             Alert(Alert.WARN, msg),
         ]
Exemple #26
0
 def run(self):
     if not os.path.exists(PORTAL_IP_FILE):
         return None
     with open(PORTAL_IP_FILE) as f:
         ips = f.read().split('\n')
         ips = filter(lambda y: bool(y), ips)
         return [
             Alert(
                 Alert.WARN,
                 _('The following IPs are bind to iSCSI Portal but were not'
                   ' found in the system: %s') % (', '.join(ips)))
         ]
Exemple #27
0
 def run(self):
     alerts = []
     regexp = re.compile(r"\[(.*)\] (.*)")
     if os.path.exists(ALERT_FILE):
         with open(ALERT_FILE) as f:
             for line in f:
                 line = line.rstrip()
                 # Line looks like [PASS|FAIL]<text>, maybe other tags
                 match = regexp.match(line)
                 lvl = Alert.WARN
                 if match:
                     if match.group(1) in (TEST_WARNING):
                         lvl = Alert.WARN
                     elif match.group(1) in (TEST_FAIL, TEST_CRITICAL):
                         lvl = Alert.CRIT
                     elif match.group(1) in (TEST_PASS):
                         lvl = Alert.OK
                     alerts.append(Alert(lvl, match.group(2)))
                 else:
                     alerts.append(Alert(lvl, line))
     return alerts
Exemple #28
0
    def run(self):

        alerts = []

        for file in os.listdir("/tmp/"):
            if file.endswith(".service_monitor"):
                full_path = '/tmp/' + file
                with open(full_path, 'r') as _file:
                    for alert_line in _file:
                        alerts.append(Alert(Alert.WARN, alert_line))

        return alerts
Exemple #29
0
    def run(self):
        not_optimal = []
        for mp in notifier().multipath_all():
            if mp.status != 'OPTIMAL':
                not_optimal.append(mp.name)

        if not_optimal:
            return [
                Alert(
                    Alert.CRIT,
                    _('The following multipaths are not optimal: %s') %
                    (', '.join(not_optimal), ))
            ]
Exemple #30
0
    def run(self):
        alerts = []
        for vol in Volume.objects.filter(vol_fstype='ZFS'):
            if vol.is_upgraded is not True:
                alerts.append(
                    Alert(
                        Alert.WARN,
                        _('New feature flags are available for volume %s. Refer '
                          'to the "Upgrading a ZFS Pool" section of the User '
                          'Guide for instructions.') % vol.vol_name,
                    ))

        return alerts