Ejemplo n.º 1
0
 def __init__(self, parameters=None):
     self.config = NatrixConfig()
     self.parameters = parameters
     # logger
     if parameters and parameters.get("logger"):
         global logger
         logger = logging.getLogger(parameters.get("logger"))
Ejemplo n.º 2
0
def rabbitmq(result, parameters):
    config = NatrixConfig()
    host = config.get_value("RABBITMQ", "host")
    port = config.get_value("RABBITMQ", "port")
    username = config.get_value("RABBITMQ", "username")
    password = config.get_value("RABBITMQ", "password")
    vhost = config.get_value("RABBITMQ", "vhost")
    credentials = pika.PlainCredentials(username, password)
    connection = pika.BlockingConnection(
        pika.ConnectionParameters(host, int(port), vhost, credentials))
    channel = connection.channel()

    queue_name = parameters.get("storage_queue")
    logger.debug("storage queue name: {}".format(queue_name))
    routing_key = parameters.get("storage_routing")
    logger.debug("storage routing key: {}".format(routing_key))

    # 声明queue, 针对需要目标url/ip的命令, 如dns, traceroute, ping, http
    if queue_name:
        channel.queue_declare(queue=queue_name, durable=True)
        # RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
        channel.basic_publish(exchange='',
                              routing_key=routing_key,
                              body=json.dumps(result))

    # 声明queue, 针对需要目标url/ip的命令,如check
    else:
        logger.error("storage queue name is empty")
    connection.close()
Ejemplo n.º 3
0
def start():
    # 1. check /etc/natrix/natrix.ini, get the AMQP paramters
    config = NatrixConfig()
    host = config.get_value("RABBITMQ", "host")
    port = config.get_value("RABBITMQ", "port")
    vhost = config.get_value("RABBITMQ", "vhost")
    username = config.get_value("RABBITMQ", "username")
    password = config.get_value("RABBITMQ", "password")

    # 4. connect to AQMP queue and consume messages
    credentials = pika.PlainCredentials(username, password)
    parameters = pika.ConnectionParameters(host,
                                           int(port),
                                           vhost,
                                           credentials=credentials)
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()

    # 5. get macaddress, create queues based on mac address
    macs = NetInfo().get_macs()
    for mac in macs:
        queue_name = const.QUEUE_COMMAND_PREFIX + mac.lower()
        logger.debug("declare rabbitmq queue: {}".format(queue_name))
        channel.queue_declare(queue=queue_name,
                              durable=True,
                              arguments={
                                  'x-message-ttl': 120000,
                                  'x-dead-letter-exchange':
                                  const.EXCHANGE_COMMAND_DEAD,
                                  'x-dead-letter-routing-key': 'dead_command'
                              })
        logger.debug("consume rabbitmq queue: {}".format(queue_name))
        channel.basic_consume(queue_callback, queue_name)
    try:
        logger.debug("start rabbitmq channel consuming")
        channel.start_consuming()
    except KeyboardInterrupt:
        logger.exception(
            "stop rabbitmq channel consuming using KeyboardInterrupt")
        channel.stop_consuming()
    except Exception:
        logger.exception("stop rabbitmq channel consuming by Exception")
        channel.stop_consuming()
    finally:
        connection.close()
Ejemplo n.º 4
0
 def __init__(self, request_parameters):
     self.parameters = request_parameters
     # logger
     if request_parameters.get("logger"):
         global logger
         logger = logging.getLogger(request_parameters.get("logger"))
         add_logger_handler(logger)
     self.check_type = request_parameters.get("type")
     self.config = NatrixConfig()
Ejemplo n.º 5
0
#!/usr/bin/env python
"""

"""
import pika, json, threading

from natrixclient.common.config import NatrixConfig
from natrixclient.common import const
from natrixclient.command.check.network import NetInfo
from natrixclient.bin.report import parse_report_basic, parse_report_advance
from natrixclient.backends.base import SingletonService
from natrixclient.backends.command_processor import processor

from .base import logger

config = NatrixConfig()
host = config.get_value("RABBITMQ", "host")
port = config.get_value("RABBITMQ", "port")
vhost = config.get_value("RABBITMQ", "vhost")
username = config.get_value("RABBITMQ", "username")
password = config.get_value("RABBITMQ", "password")


class CommandService(threading.Thread):
    """

    """
    def run(self):
        # 4. connect to AQMP queue and consume messages
        credentials = pika.PlainCredentials(username, password)
        parameters = pika.ConnectionParameters(host,
Ejemplo n.º 6
0
# -*- coding: utf-8 -*-
"""

"""
import sys

from natrixclient.common.config import NatrixConfig
from natrixclient.backends import mqtt, rabbitmq

natrix_config = NatrixConfig()


def start():
    backend_type = natrix_config.get_value("SERVICE", "backend").lower()
    if backend_type == "mqtt":
        mqtt.start()
    elif backend_type == "rabbitmq":
        rabbitmq.start()
    else:
        print("Get an unexpective backend type: {}".format(backend_type))


def stop():
    pass


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Should choose action: start/stop")
        exit(1)
Ejemplo n.º 7
0
class NetInfo(object):
    # 初始化固有属性macaddr,localip,netmask,gateway,hostname
    def __init__(self, parameters=None):
        self.config = NatrixConfig()
        self.parameters = parameters
        # logger
        if parameters and parameters.get("logger"):
            global logger
            logger = logging.getLogger(parameters.get("logger"))

    def ping_access(self, website, interface):
        access = False
        try:
            logger.debug("ping website {} using interface {}".format(
                website, interface))
            pobj = Ping(destination=website, parameters=self.parameters)
            presult = pobj.ping()
            if presult:
                access = True
            else:
                logger.error(
                    "ping website {} using interface {} got empty result".
                    format(website, interface))
        except Exception as e:
            logger.exception(
                "ping website {} using interface {} cause exception: {}".
                format(website, interface, e))
        return access

    # 请输入互联网网站
    # 如果不存在, 默认能访互联网, 返回True
    # 如果存在, 只要有任何一个能访问, 就代表能访问, 返回True
    def access_internet(self, interface):
        access = True
        try:
            internet_websites = self.config.get_value("NETWORK",
                                                      "internet_websites")
            internet_websites = internet_websites.replace("[", "").replace("]", "").replace("\"", "").\
                replace("'", "").replace(" ", "")
            if internet_websites:
                websites = internet_websites.split(",")
                for website in websites:
                    website = website.strip()
                    logger.debug(
                        "access internet {} using interface {}".format(
                            website, interface))
                    access = self.ping_access(website, interface)
                    if access:
                        logger.debug(
                            "interface {} can access internet {}".format(
                                interface, website))
                        break
                    else:
                        logger.warning(
                            "interface {} cannot access internet {}".format(
                                interface, website))
            else:
                logger.error(
                    "please set NETWORK: internet_websites in {}".format(
                        CONFIG_PATH))
        except KeyError as ke:
            logger.exception(
                "fail to get NETWORK:internet_websites from configuration file {}. \nexception: {}"
                .format(CONFIG_PATH, str(ke)))
        return access

    # 请输入公司内网网站域名
    # 如果不存在, 默认能访问公司HTTP网络, 返回True
    # 如果存在, 只要有任何一个能访问, 就代表能访问, 返回True
    def access_corporate(self, interface):
        access = True
        try:
            corporate_websites = self.config.get_value("NETWORK",
                                                       "corporate_websites")
            corporate_websites = corporate_websites.replace("[", "").replace("]", "").replace("\"", "").\
                replace("'", "").replace(" ", "")
            if corporate_websites:
                websites = corporate_websites.split(",")
                for website in websites:
                    website = website.strip()
                    logger.debug(
                        "access corporate {} using interface {}".format(
                            website, interface))
                    access = self.ping_access(website, interface)
                    if access:
                        logger.debug(
                            "interface {} can access corporate {}".format(
                                interface, website))
                        break
                    else:
                        logger.warning(
                            "interface {} cannot access corporate {}".format(
                                interface, website))
            else:
                logger.error(
                    "please set NETWORK:corporate_websites in {}".format(
                        CONFIG_PATH))
        except KeyError as ke:
            logger.exception(
                "fail to get NETWORK:corporate_websites from configuration file {}. \nexception: {}"
                .format(CONFIG_PATH, str(ke)))
        return access

    # 请输入公司局域网IP
    # 如果不存在, 默认能访问公司内部网络, 返回True
    # 如果存在, 只要有任何一个能访问, 就代表能访问, 返回True
    def access_intranet(self, interface):
        access = True
        try:
            intranet_ips = self.config.get_value("NETWORK", "intranet_ips")
            intranet_ips = intranet_ips.replace("[", "").replace(
                "]", "").replace("\"", "").replace("'", "").replace(" ", "")
            if intranet_ips:
                ips = intranet_ips.split(",")
                for ip in ips:
                    ip = ip.strip()
                    logger.debug(
                        "access intranet {} using interface {}".format(
                            ip, interface))
                    access = self.ping_access(ip, interface)
                    if access:
                        logger.debug(
                            "interface {} can access intranet {}".format(
                                interface, ip))
                        break
                    else:
                        logger.warning(
                            "interface {} cannot access intranet {}".format(
                                interface, ip))
            else:
                logger.error(
                    "please set NETWORK:intranet_websites in {}".format(
                        CONFIG_PATH))
        except KeyError as ke:
            logger.exception(
                "fail to get NETWORK:intranet_websites from configuration file {}. \nexception: {}"
                .format(CONFIG_PATH, str(ke)))
        return access

    @staticmethod
    def set_gateways(interfaces_json):
        netgateways = netifaces.gateways()
        gateways = netgateways.get(netifaces.AF_INET)
        for gateway in gateways:
            gw = gateway[0]
            gintf = gateway[1]
            gdefault = gateway[2]
            interfaces_json[gintf]["gateway"] = gw
            interfaces_json[gintf]["is_default"] = gdefault

    # 获取主机名,如果主机名不符合规范,重设主机名
    @staticmethod
    def set_hostname():
        macaddress = NetInfo.get_default_mac().replace(":", "")
        default_hostname = "pi-" + macaddress
        init_hostname = socket.gethostname()
        logger.debug("get hostname = %s" % init_hostname)
        # self.hostname = inithostname
        if init_hostname != default_hostname:
            logger.debug("set hostname = %s" % init_hostname)
            # 重设主机名
            args = "hostname  %s " % default_hostname
            subprocess.Popen(args, shell=True,
                             stdout=subprocess.PIPE).communicate()

            # 修改/etc/hostname文件
            f = open('/etc/hostname', 'w')
            f.write(default_hostname)
            f.close()

            # 修改/etc/hosts
            if 'linux' in sys.platform or 'darwin' in sys.platform:
                filename = '/etc/hosts'
            else:
                filename = 'c:\windows\system32\drivers\etc\hosts'

            hosts = Hosts(path=filename)
            # 移除旧域名
            hosts.remove_all_matching(name=init_hostname)
            new_entry = HostsEntry(entry_type='ipv4',
                                   address='127.0.0.1',
                                   names=[default_hostname])
            hosts.add([new_entry])
            hosts.write()

    # 得到单独的接口信息
    # 网络类型
    # WIRED = "wired"
    # WIRELESS = "wireless"
    # MOBILE = "dns"
    # CELLULAR_3G = "3G"
    # CELLULAR_4G = "4G"
    # UNKNOWN = "unknown"
    @staticmethod
    def get_interface(interface):
        interface_json = {"type": "wired", "name": interface}
        wireless_keys = ["wlan"]
        for wireless_key in wireless_keys:
            if interface.find(wireless_key) >= 0:
                interface_json["type"] = "wireless"
                break
        info = netifaces.ifaddresses(interface)
        # 地址信息
        interface_json["macaddress"] = None
        info_mac = info.get(netifaces.AF_LINK)
        if info_mac:
            if len(info_mac) == 1:
                interface_json["macaddress"] = info_mac[0].get("addr").replace(
                    ":", "").lower()
            else:
                logger.error(
                    "get mac address for interface {} wrong: {}".format(
                        interface, str(info_mac)))
        else:
            logger.error(
                "cannot get mac address for interface {}".format(interface))

        # ip地址信息, need to consider with gateway
        info_ipv4 = info.get(netifaces.AF_INET)
        if info_ipv4 and len(info_ipv4) == 1:
            local_ip = info_ipv4[0].get("addr")
            interface_json["local_ip"] = local_ip
            interface_json["local_location"] = IpLocation.get_location(
                local_ip)
            interface_json["netmask"] = info_ipv4[0].get("netmask")
            interface_json["broadcast"] = info_ipv4[0].get("broadcast")
            interface_json["is_default"] = False
        elif info_ipv4 and len(info_ipv4) > 1:
            """
            存在1个接口对应n个IP, 例如
            $ ip addr
            1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
                link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
                inet 127.0.0.1/8 scope host lo
                   valid_lft forever preferred_lft forever
                inet6 ::1/128 scope host 
                   valid_lft forever preferred_lft forever
            2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
                link/ether b8:27:eb:f9:41:74 brd ff:ff:ff:ff:ff:ff
                inet 10.10.36.222/24 brd 10.10.36.255 scope global eth0
                   valid_lft forever preferred_lft forever
                inet 10.10.36.55/24 brd 10.10.36.255 scope global secondary eth0
                   valid_lft forever preferred_lft forever
                inet6 fe80::ba27:ebff:fef9:4174/64 scope link 
                   valid_lft forever preferred_lft forever
            """
            msg = "interface: {} have {} ip, natrix do not support, please check your network!".format(
                interface, len(info))
            logger.warning(msg)

            local_ip = None
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                # doesn't even have to be reachable
                s.connect(('10.255.255.255', 1))
                local_ip = s.getsockname()[0]
            except Exception:
                msg = "Cannot get an default ip for interface {}".format(
                    interface)
                logger.exception(msg)

            if local_ip:
                for info in info_ipv4:
                    if info.get("addr") == local_ip:
                        interface_json["local_ip"] = info.get("addr")
                        interface_json[
                            "local_location"] = IpLocation.get_location(
                                local_ip)
                        interface_json["netmask"] = info.get("netmask")
                        interface_json["broadcast"] = info.get("broadcast")
                        interface_json["is_default"] = False

            if not interface_json.get("local_ip"):
                interface_json["local_ip"] = None
                interface_json["local_location"] = None
                interface_json["netmask"] = None
                interface_json["broadcast"] = None
                interface_json["is_default"] = False
        else:
            msg = "interface {} do not have IPV4 address".format(interface)
            logger.warning(msg)
            interface_json["local_ip"] = None
            interface_json["local_location"] = None
            interface_json["netmask"] = None
            interface_json["broadcast"] = None
            interface_json["is_default"] = False

        # in all situation, set gateway to None
        interface_json["gateway"] = None

        # 公网IP
        if interface_json["local_ip"]:
            public_ip = IpPublic.get_publicip(interface)
            interface_json["public_ip"] = public_ip
        else:
            interface_json["public_ip"] = None

        if interface_json.get("public_ip"):
            interface_json["public_location"] = IpLocation.get_location(
                interface_json.get("public_ip"))
        else:
            interface_json["public_location"] = None
        return interface_json

    # 得到所有的接口信息
    @staticmethod
    def get_interfaces():
        interfaces_json = {}
        for interface in netifaces.interfaces():
            if interface != "lo":
                interface_json = NetInfo.get_interface(interface)
                interfaces_json[interface] = interface_json
        # 设置 gateway 和 is_default 信息
        NetInfo.set_gateways(interfaces_json)
        # 设置名称
        # NetInfo.set_hostname(interfaces_json)
        # 解析网关信息
        return interfaces_json

    def get_access_interface(self, interface):
        interface_json = {"type": "wired", "name": interface}
        wireless_keys = ["wlan"]
        for wireless_key in wireless_keys:
            if interface.find(wireless_key) >= 0:
                interface_json["type"] = "wireless"
                break
        info = netifaces.ifaddresses(interface)
        # 地址信息
        interface_json["macaddress"] = None
        info_mac = info.get(netifaces.AF_LINK)
        if info_mac:
            if len(info_mac) == 1:
                interface_json["macaddress"] = info_mac[0].get("addr").replace(
                    ":", "").lower()
            else:
                logger.error(
                    "get mac address for interface {} wrong: {}".format(
                        interface, str(info_mac)))
        else:
            logger.error(
                "cannot get mac address for interface {}".format(interface))

        ipl = IpLocation(self.parameters)
        ipp = IpPublic(self.parameters)

        # ip地址信息, need to consider with gateway
        info_ipv4 = info.get(netifaces.AF_INET)
        if info_ipv4 and len(info_ipv4) == 1:
            local_ip = info_ipv4[0].get("addr")
            interface_json["local_ip"] = local_ip
            interface_json["local_location"] = ipl.get_location(local_ip)
            interface_json["netmask"] = info_ipv4[0].get("netmask")
            interface_json["broadcast"] = info_ipv4[0].get("broadcast")
            interface_json["is_default"] = False
        elif info_ipv4 and len(info_ipv4) > 1:
            """
            存在1个接口对应n个IP, 例如
            $ ip addr
            1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
                link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
                inet 127.0.0.1/8 scope host lo
                   valid_lft forever preferred_lft forever
                inet6 ::1/128 scope host 
                   valid_lft forever preferred_lft forever
            2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
                link/ether b8:27:eb:f9:41:74 brd ff:ff:ff:ff:ff:ff
                inet 10.10.36.222/24 brd 10.10.36.255 scope global eth0
                   valid_lft forever preferred_lft forever
                inet 10.10.36.55/24 brd 10.10.36.255 scope global secondary eth0
                   valid_lft forever preferred_lft forever
                inet6 fe80::ba27:ebff:fef9:4174/64 scope link 
                   valid_lft forever preferred_lft forever
            """
            msg = "interface: {} have {} ip, natrix do not support, please check your network!".format(
                interface, len(info))
            logger.warning(msg)

            local_ip = None
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            try:
                # doesn't even have to be reachable
                s.connect(('10.255.255.255', 1))
                local_ip = s.getsockname()[0]
            except Exception:
                msg = "Cannot get an default ip for interface {}".format(
                    interface)
                logger.exception(msg)

            if local_ip:
                for info in info_ipv4:
                    if info.get("addr") == local_ip:
                        interface_json["local_ip"] = info.get("addr")
                        interface_json["local_location"] = ipl.get_location(
                            local_ip)
                        interface_json["netmask"] = info.get("netmask")
                        interface_json["broadcast"] = info.get("broadcast")
                        interface_json["is_default"] = False

            if not interface_json.get("local_ip"):
                interface_json["local_ip"] = None
                interface_json["local_location"] = None
                interface_json["netmask"] = None
                interface_json["broadcast"] = None
                interface_json["is_default"] = False
        else:
            msg = "interface {} do not have IPV4 address".format(interface)
            logger.warning(msg)
            interface_json["local_ip"] = None
            interface_json["local_location"] = None
            interface_json["netmask"] = None
            interface_json["broadcast"] = None
            interface_json["is_default"] = False

        # in all situation, set gateway to None
        interface_json["gateway"] = None

        # 公网IP
        if interface_json["local_ip"]:
            public_ip = ipp.get_publicip(interface)
            interface_json["public_ip"] = public_ip
        else:
            interface_json["public_ip"] = None

        if interface_json.get("public_ip"):
            interface_json["public_location"] = ipl.get_location(
                interface_json.get("public_ip"))
        else:
            interface_json["public_location"] = None

        # 连接信息
        if interface_json["local_ip"]:
            interface_json["access_intranet"] = self.access_intranet(interface)
            interface_json["access_corporate"] = self.access_corporate(
                interface)
            interface_json["access_internet"] = self.access_internet(interface)
        else:
            interface_json["access_intranet"] = False
            interface_json["access_corporate"] = False
            interface_json["access_internet"] = False
        return interface_json

    # 得到所有的接口信息
    def get_access_interfaces(self):
        interfaces_json = {}
        for interface in netifaces.interfaces():
            if interface != "lo":
                interface_access_json = self.get_access_interface(interface)
                interfaces_json[interface] = interface_access_json
        # 设置 gateway 和 is_default 信息
        NetInfo.set_gateways(interfaces_json)
        # 设置名称
        # NetInfo.set_hostname(interfaces_json)
        # 解析网关信息
        return interfaces_json

    # 得到接口的IP地址
    # 方法写道natrixclient.common.nettools
    @staticmethod
    def get_ip(interface):
        local_ip = None
        info = netifaces.ifaddresses(interface)
        info_ipv4 = info.get(netifaces.AF_INET)
        if info_ipv4:
            # 存在1个接口对应n个IP
            if len(info_ipv4) > 1:
                msg = "interface: {} have {} ips, please check your network!".format(
                    interface, len(info_ipv4))
                logger.warning(msg)
            local_ip = info_ipv4[0].get("addr")
        return local_ip

    # 得到所有接口的IP地址
    @staticmethod
    def get_ips():
        ips = {}
        for interface in netifaces.interfaces():
            if interface == "lo":
                continue
            ip = NetInfo.get_ip(interface)
            ip_dict = {"interface": interface, "ip": ip}
            ips.append(ip_dict)
        return ips

    @staticmethod
    def get_default_mac():
        interface_json = NetInfo.get_interfaces()
        # 如果有缺省的使用缺省的
        for key, interface_json in interface_json.items():
            if interface_json.get("is_default") and interface_json.get(
                    "macaddress"):
                return interface_json.get("macaddress")
        # 如果没有缺省的, 使用第一个非空的
        for interface in interface_json:
            interface_json = json.loads(interface)
            if interface_json.get("macaddress"):
                return interface_json.get("macaddress")
        # 2个都不满足, 返回空
        return None

    # 得到接口的mac地址信息
    @staticmethod
    def get_mac(interface):
        info = netifaces.ifaddresses(interface)
        # 地址信息
        mac = None
        info_mac = info.get(netifaces.AF_LINK)
        if info_mac:
            if len(info_mac) == 1:
                mac = info_mac[0].get("addr").replace(":", "").lower()
            else:
                logger.error(
                    "get mac address for interface {} wrong: {}".format(
                        interface, str(info_mac)))
        else:
            logger.error(
                "cannot get mac address for interface {}".format(interface))
        return mac

    # 得到所有的mac地址信息
    @staticmethod
    def get_macs():
        macs = []
        for interface in netifaces.interfaces():
            if interface == "lo":
                continue
            mac = NetInfo.get_mac(interface)
            if mac:
                macs.append(mac)
        return macs

    @staticmethod
    def get_basic():
        return NetInfo.get_interfaces()

    def get_advance(self):
        return self.get_access_interfaces()
Ejemplo n.º 8
0
# -*- coding: utf-8 -*-
import logging
from logging.handlers import WatchedFileHandler

from natrixclient.common.config import NatrixConfig
from natrixclient.common.const import FILE_LOGGING_FORMAT, FILE_LOGGING_DATE_FORMAT, CONSOLE_LOGGING_FORMAT

natrix_config = NatrixConfig()
log_directory = natrix_config.get_value('COMMON', 'log_directory')
log_level = logging.getLevelName(
    natrix_config.get_value('COMMON', 'log_level').upper())


def add_logger(logger_name,
               file_name=None,
               parent=None,
               propagate=False,
               log_level='INFO',
               log_dir='/var/log/natrixclient'):
    """Add a new logger

    :param logger_name:
    :param file_name:
    :param parent:
    :param propagate:
    :param log_level:
    :param log_dir:
    :return:
    """
    logger = logging.getLogger(logger_name)
    logger.propagate = propagate
Ejemplo n.º 9
0
 def __init__(self, request_parameters):
     self.parameters = request_parameters
     self.check_type = request_parameters.get('type')
     # not use
     self.config = NatrixConfig()