Example #1
0
    def _do_call(self, obj, targets=None, registry=None):  # pylint: disable=unused-argument
        if not targets:
            targets = self.targets

        param_target = obj.get_params().get('target')

        for target in targets:
            (data, conn) = (None, None)
            command = 'info'
            command_args = []
            cfg = target.config

            for x in ('socket_timeout', 'socket_connect_timeout'):
                if cfg.get(x) is not None:
                    cfg[x] = float(cfg[x])
                else:
                    cfg[x] = None

            if 'command' in cfg:
                command = cfg.pop('command').lower()

            if 'command_args' in cfg:
                command_args = list(cfg.pop('command_args') or [])

            if command not in _ALLOWED_COMMANDS:
                raise CovenantConfigurationError("invalid redis command: %r" %
                                                 command)

            if target.credentials:
                cfg['username'] = target.credentials['username']
                cfg['password'] = target.credentials['password']

            try:
                if param_target and not cfg.get('url'):
                    cfg['url'] = param_target

                if cfg.get('url'):
                    conn = redis.from_url(**cfg)
                else:
                    conn = redis.Redis(**cfg)

                data = getattr(conn, command)(*command_args)
            except Exception as e:
                data = CovenantTargetFailed(e)
                LOG.exception("error on target: %r. exception: %r",
                              target.name, e)

            target(data)

        return self.generate_latest(registry)
Example #2
0
    def _do_call(self, obj, targets=None, registry=None):  # pylint: disable=unused-argument
        if not targets:
            targets = self.targets

        param_target = obj.get_params().get('target')

        for target in targets:
            (data, conn) = (None, None)

            cfg = target.config
            common_name = cfg.get('common_name')
            cfg['verify_peer'] = cfg.get('verify_peer', True)
            cfg['ip_protocol'] = _IP_PROTOCOLS.get(cfg.get('ip_protocol'),
                                                   socket.AF_INET)

            if cfg.get('timeout') is not None:
                cfg['timeout'] = float(cfg['timeout'])
            else:
                cfg['timeout'] = None

            if param_target and not cfg.get('uri'):
                uri = param_target
            else:
                uri = cfg.get('uri')

            if not uri:
                raise CovenantConfigurationError(
                    "missing uri or target in configuration")

            uri_split = urisup.uri_help_split(uri)
            scheme = None

            if not isinstance(uri_split[1], tuple):
                host = uri_split[0]
                port = uri_split[2]
            elif uri_split[1]:
                scheme = uri_split[0]
                host, port = uri_split[1][2:4]
            else:
                raise CovenantConfigurationError(
                    "missing host and port in uri: %r" % uri)

            if not host:
                raise CovenantConfigurationError(
                    "missing or invalid host in uri: %r" % uri)

            if scheme and not port:
                try:
                    port = socket.getservbyname(scheme)
                except socket.error:
                    pass

            if not port:
                raise CovenantConfigurationError(
                    "missing or invalid port in uri: %r" % uri)

            data = {
                'connect_success': False,
                'cert_secure': False,
                "%s_success" % self.type: False
            }

            conn = None

            try:
                server_hostname = common_name or host

                context = ssl.create_default_context()
                context.check_hostname = False
                context.verify_mode = ssl.CERT_NONE

                self._load_context_options(context, cfg.get('options'))

                conn = self._connect(context, host, port, server_hostname,
                                     cfg['ip_protocol'], cfg['timeout'])

                data['cipher_info'] = conn.cipher()[0]
                data['version_info'] = conn.version()

                valid_hosts = {'subject': [], 'subjectAltName': []}

                cert_der = conn.getpeercert(True)
                if cert_der:
                    self._subject_alt_name(
                        self._load_cert(cert_der, data)[0], data, valid_hosts)
                    data['hostname_valid'] = self._valid_hostname(
                        valid_hosts, server_hostname)

                    if cfg['verify_peer']:
                        if conn:
                            conn.shutdown(socket.SHUT_RDWR)
                            conn.close()
                            conn = None

                        context.verify_mode = ssl.CERT_REQUIRED
                        context.load_default_certs(ssl.Purpose.SERVER_AUTH)
                        conn = self._connect(context, host, port,
                                             server_hostname,
                                             cfg['ip_protocol'],
                                             cfg['timeout'])
            except ssl.SSLError as e:
                LOG.warning("ssl error on target: %r. exception: %r",
                            target.name, e)
            except Exception as e:
                data = CovenantTargetFailed(e)
                LOG.exception("error on target: %r. exception: %r",
                              target.name, e)
            else:
                if data.get('connect_success'):
                    if not cfg['verify_peer']:
                        data["%s_success" % self.type] = True
                    elif not data.get('cert_has_expired') \
                       and data.get('hostname_valid'):
                        data['cert_secure'] = True
                        data["%s_success" % self.type] = True
            finally:
                if conn:
                    conn.shutdown(socket.SHUT_RDWR)
                    conn.close()

            target(data)

        return self.generate_latest(registry)
Example #3
0
def load_conf(xfile, options = None):
    signal.signal(signal.SIGTERM, stop)
    signal.signal(signal.SIGINT, stop)

    config_dir = os.path.dirname(os.path.abspath(xfile))

    with open(xfile, 'r') as f:
        conf = parse_conf(load_yaml(f))

    for name, module in six.iteritems(MODULES):
        LOG.info("module init: %r", name)
        module.init(conf)

    for x in ('module', 'plugin', 'filter'):
        path = conf['general'].get('%ss_path' % x)
        if path and os.path.isdir(path):
            DwhoLibLoader.load_dir(x, path)

    if not conf.get('endpoints'):
        raise CovenantConfigurationError("Missing 'endpoints' section in configuration")

    for name, ept_cfg in six.iteritems(conf['endpoints']):
        cfg     = {'general':  copy.copy(conf['general']),
                   'covenant': {'endpoint_name': name,
                                'config_dir':    config_dir},
                   'vars' :    {}}
        metrics = []
        probes = []

        if 'plugin' not in ept_cfg:
            raise CovenantConfigurationError("Missing 'plugin' option in endpoint: %r" % name)

        if ept_cfg['plugin'] not in PLUGINS:
            raise CovenantConfigurationError("Invalid plugin %r in endpoint: %r"
                                             % (ept_cfg['plugin'],
                                                name))
        cfg['covenant']['plugin_name'] = ept_cfg['plugin']

        if ept_cfg.get('import_vars'):
            cfg['vars'].update(import_file(ept_cfg['import_vars'], config_dir, cfg))

        if 'vars' in ept_cfg:
            cfg['vars'].update(copy.deepcopy(ept_cfg['vars']))

        if ept_cfg.get('import_metrics'):
            metrics.extend(import_file(ept_cfg['import_metrics'], config_dir, cfg))

        if 'metrics' in ept_cfg:
            metrics.extend(copy.deepcopy(ept_cfg['metrics']))

        if ept_cfg.get('import_probes'):
            probes.extend(import_file(ept_cfg['import_probes'], config_dir, cfg))

        if 'probes' in ept_cfg:
            probes.extend(copy.deepcopy(ept_cfg['probes']))

        if not metrics and not probes:
            raise CovenantConfigurationError("Missing 'metrics' or 'probes' option in endpoint: %r" % name)

        if metrics and probes:
            raise CovenantConfigurationError("'metrics' and 'probes' aren't allowed in a same endpoint: %r" % name)

        cfg['credentials'] = None
        if ept_cfg.get('credentials'):
            cfg['credentials'] = ept_cfg['credentials']

        cfg['metrics'] = metrics
        cfg['probes'] = probes

        endpoint = PLUGINS[ept_cfg['plugin']](name)
        ENDPOINTS.register(endpoint)
        LOG.info("endpoint init: %r", name)
        endpoint.init(cfg)
        LOG.info("endpoint safe_init: %r", name)
        endpoint.safe_init()
        DWHO_THREADS.append(endpoint.at_stop)

    if not options or not isinstance(options, object):
        return conf

    for def_option in six.iterkeys(get_default_options()):
        if getattr(options, def_option, None) is None \
           and def_option in conf['general']:
            setattr(options, def_option, conf['general'][def_option])

    setattr(options, 'configuration', conf)

    return options
Example #4
0
    def _do_call(self, obj, targets = None, registry = None): # pylint: disable=unused-argument
        if not targets:
            targets = self.targets

        for target in targets:
            (data, req) = (None, None)

            cfg         = target.config
            method      = 'get'
            xformat     = None

            if 'format' in cfg:
                xformat = cfg.pop('format').lower()

            if 'uri' in cfg and not cfg.get('url'):
                cfg['url'] = cfg.pop('uri')

            if 'method' in cfg:
                method = cfg.pop('method').lower()

            if 'ssl_verify' in cfg:
                cfg['verify'] = bool(cfg.pop('ssl_verify'))

            if cfg.get('timeout') is not None:
                cfg['timeout'] = float(cfg['timeout'])
            else:
                cfg['timeout'] = None

            if not isinstance(cfg.get('headers'), dict):
                cfg['headers'] = None

            if target.credentials:
                cfg['auth'] = (target.credentials['username'],
                               target.credentials['password'])

            if method not in _ALLOWED_METHODS:
                raise CovenantConfigurationError("invalid http method: %r" % method)

            try:
                req = getattr(requests, method)(**cfg)

                if req.status_code != requests.codes['ok']:
                    raise LookupError("invalid status code: %r. (error: %r)"
                                      % (req.status_code, req.text))

                if xformat == 'json':
                    data = req.json()
                else:
                    data = req.text
            except Exception as e:
                data = CovenantTargetFailed(e)
                LOG.exception("error on target: %r. exception: %r",
                              target.name,
                              e)
            finally:
                if req:
                    req.close()

            target(data)

        return self.generate_latest(registry)