glances_ip.py 4.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2015 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""IP plugin."""

# Import Glances libs
A
Alessio Sergi 已提交
23
from glances.core.compat import iterkeys
24
from glances.core.glances_globals import is_freebsd
25 26 27
from glances.core.glances_logging import logger
from glances.plugins.glances_plugin import GlancesPlugin

28 29 30 31 32 33 34 35 36 37 38
# XXX FreeBSD: Segmentation fault (core dumped)
# -- https://bitbucket.org/al45tair/netifaces/issues/15
if not is_freebsd:
    try:
        import netifaces
        netifaces_tag = True
    except ImportError:
        netifaces_tag = False
else:
    netifaces_tag = False

39 40 41

class Plugin(GlancesPlugin):

A
PEP 257  
Alessio Sergi 已提交
42
    """Glances IP Plugin.
43 44 45 46 47 48

    stats is a dict
    """

    def __init__(self, args=None):
        """Init the plugin."""
A
Alessio Sergi 已提交
49
        super(Plugin, self).__init__(args=args)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

        # We want to display the stat in the curse interface
        self.display_curse = True

        # Init the stats
        self.reset()

    def reset(self):
        """Reset/init the stats."""
        self.stats = {}

    @GlancesPlugin._log_result_decorator
    def update(self):
        """Update IP stats using the input method.

        Stats is dict
        """
        # Reset stats
        self.reset()

70
        if self.input_method == 'local' and netifaces_tag:
71 72 73
            # Update stats using the netifaces lib
            try:
                default_gw = netifaces.gateways()['default'][netifaces.AF_INET]
N
nicolargo 已提交
74
            except (KeyError, AttributeError) as e:
75
                logger.debug("Cannot grab the default gateway ({0})".format(e))
76 77 78 79 80 81
            else:
                try:
                    self.stats['address'] = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['addr']
                    self.stats['mask'] = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['netmask']
                    self.stats['mask_cidr'] = self.ip_to_cidr(self.stats['mask'])
                    self.stats['gateway'] = netifaces.gateways()['default'][netifaces.AF_INET][0]
N
nicolargo 已提交
82
                except (KeyError, AttributeError) as e:
83
                    logger.debug("Cannot grab IP information: {0}".format(e))
84
        elif self.input_method == 'snmp':
85 86 87 88 89 90 91 92 93
            # Not implemented yet
            pass

        # Update the view
        self.update_views()

        return self.stats

    def update_views(self):
A
PEP 257  
Alessio Sergi 已提交
94
        """Update stats views."""
95
        # Call the father's method
A
Alessio Sergi 已提交
96
        super(Plugin, self).update_views()
97 98 99

        # Add specifics informations
        # Optional
A
Alessio Sergi 已提交
100
        for key in iterkeys(self.stats):
101 102 103 104 105 106 107 108 109 110 111 112
            self.views[key]['optional'] = True

    def msg_curse(self, args=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or args.disable_ip:
            return ret

        # Build the string message
A
Alessio Sergi 已提交
113
        msg = ' - '
N
nicolargo 已提交
114
        ret.append(self.curse_add_line(msg))
A
Alessio Sergi 已提交
115
        msg = 'IP '
116
        ret.append(self.curse_add_line(msg, 'TITLE'))
N
nicolargo 已提交
117
        msg = '{0:}/{1}'.format(self.stats['address'], self.stats['mask_cidr'])
118 119 120 121 122 123
        ret.append(self.curse_add_line(msg))

        return ret

    @staticmethod
    def ip_to_cidr(ip):
A
PEP 257  
Alessio Sergi 已提交
124 125 126 127
        """Convert IP address to CIDR.

        Example: '255.255.255.0' will return 24
        """
128
        return sum([int(x) << 8 for x in ip.split('.')]) // 8128