예제 #1
0
    def process_config(self, file_hash, config, host):
        """Manages all translations related to a config file.

        Publish tables to PE.
        :param file_hash: Hash of the configuration file
        :param config: object representing the configuration
        :param host: Remote host name
        :return: True if config was processed
        """
        try:
            LOG.debug("process_config hash=%s" % file_hash)
            template_hash = config['template']
            template = self.known_templates.get(template_hash, None)
            if template is None:
                waiting = (
                    self.templates_awaited_by_config.get(template_hash, []))
                waiting.append((file_hash, config))
                self.templates_awaited_by_config[template_hash] = waiting
                LOG.debug('Template %s not yet registered' % template_hash)
                return False

            host_id = utils.compute_hash(host)

            namespaces = [self.known_namespaces.get(h, None).get('data', None)
                          for h in template['namespaces']]

            conf = parsing.construct_conf_manager(namespaces)
            parsing.add_parsed_conf(conf, config['data'])

            for tablename in set(self.get_schema()) - set(self.state):
                self.state[tablename] = set()
                self.publish(tablename, self.state[tablename],
                             use_snapshot=False)

            self.translate_conf(conf, file_hash)

            self.translate_host(host_id, host)

            self.translate_service(
                host_id, config['service'], config['version'])

            file_name = os.path.basename(config['path'])
            self.translate_file(file_hash, host_id, template_hash, file_name)

            ns_hashes = {h: self.known_namespaces[h]['name']
                         for h in template['namespaces']}
            self.translate_template_namespace(template_hash, template['name'],
                                              ns_hashes)

            for tablename in self.state:
                self.publish(tablename, self.state[tablename],
                             use_snapshot=True)
            return True
        except KeyError:
            LOG.error('Config %s from %s NOT registered'
                      % (file_hash, host))
            return False
예제 #2
0
    def parse(self, host):
        """Parses the config at the path given. Updates data and hash.

        host: the name of the host where the config is. Used for building a
        unique hash.
        """
        namespaces_data = [ns.data for ns in self.template.namespaces]
        conf = parsing.parse_config_file(namespaces_data, self.path)

        Config.sanitize_config(conf)
        self.data = conf._namespace._normalized

        self.hash = utils.compute_hash(host, self.template.hash,
                                       json.dumps(self.data, sort_keys=True))
예제 #3
0
파일: agent.py 프로젝트: openstack/congress
    def parse(self, host):
        """Parses the config at the path given. Updates data and hash.

        host: the name of the host where the config is. Used for building a
        unique hash.
        """
        namespaces_data = [ns.data for ns in self.template.namespaces]
        conf = parsing.parse_config_file(namespaces_data, self.path)

        Config.sanitize_config(conf)
        self.data = conf._namespace._normalized

        self.hash = utils.compute_hash(host, self.template.hash,
                                       json.dumps(self.data, sort_keys=True))
예제 #4
0
    def process_config(self, file_hash, config, host):
        """Manages all translations related to a config file.

        Publish tables to PE.
        :param file_hash: Hash of the configuration file
        :param config: object representing the configuration
        :param host: Remote host name
        """
        template_hash = config['template']
        template = self.known_templates.get(template_hash, None)
        if template is None:
            waiting = self.templates_awaited_by_config.get(template_hash, [])
            waiting.append((file_hash, config))
            self.templates_awaited_by_config[template_hash] = waiting
            LOG.info('Template %s not yet registered' % template_hash)
            return

        host_id = utils.compute_hash(host)

        namespaces = [
            self.known_namespaces.get(h, None).get('data', None)
            for h in template['namespaces']
        ]

        conf = parsing.construct_conf_manager(namespaces)
        parsing.add_parsed_conf(conf, config['data'])

        for tablename in set(self.get_schema()) - set(self.state):
            self.state[tablename] = set()
            self.publish(tablename, self.state[tablename], use_snapshot=False)

        self.translate_conf(conf, file_hash)

        self.translate_host(host_id, host)

        self.translate_service(host_id, config['service'], config['version'])

        file_name = os.path.basename(config['path'])
        self.translate_file(file_hash, host_id, template_hash, file_name)

        ns_hashes = {
            h: self.known_namespaces[h]['name']
            for h in template['namespaces']
        }
        self.translate_template_namespace(template_hash, template['name'],
                                          ns_hashes)

        for tablename in self.state:
            self.publish(tablename, self.state[tablename], use_snapshot=True)
예제 #5
0
    def load(template_path):
        """Loads a template configuration file

        :param template_path: path to the template
        :return: a fully configured Template object.
        """
        namespaces, output_file = Template._parse_template_conf(template_path)

        template = Template(template_path, output_file)

        for namespace in namespaces:
            template.namespaces.append(Namespace.load(namespace))

        template.hash = utils.compute_hash(
            sorted([ns.hash for ns in template.namespaces]))

        return template
예제 #6
0
def construct_conf_manager(namespaces):
    """Construct a config manager from a list of namespaces data.

    Register options of given namespaces into a cfg.ConfigOpts object.
    A namespaces dict is typically cfg_validator.generator output. Options are
    provided an hash as an extra field.

    :param namespaces: A list of dict, containing options metadata.
    :return: A cfg.ConfigOpts.
    """
    conf = cfg.ConfigOpts()

    for ns_dict in namespaces:
        ns_hash = utils.compute_hash(json.dumps(ns_dict, sort_keys=True))
        add_namespace(conf, ns_dict, ns_hash)

    return conf
예제 #7
0
def construct_conf_manager(namespaces):
    """Construct a config manager from a list of namespaces data.

    Register options of given namespaces into a cfg.ConfigOpts object.
    A namespaces dict is typically cfg_validator.generator output. Options are
    provided an hash as an extra field.

    :param namespaces: A list of dict, containing options metadata.
    :return: A cfg.ConfigOpts.
    """
    conf = cfg.ConfigOpts()

    for ns_dict in namespaces:
        ns_hash = utils.compute_hash(json.dumps(ns_dict, sort_keys=True))
        add_namespace(conf, ns_dict, ns_hash)

    return conf
예제 #8
0
파일: agent.py 프로젝트: openstack/congress
    def load(template_path):
        """Loads a template configuration file

        :param template_path: path to the template
        :return: a fully configured Template object.
        """
        namespaces, output_file = Template._parse_template_conf(template_path)

        template = Template(template_path, output_file)

        for namespace in namespaces:
            template.namespaces.append(Namespace.load(namespace))

        template.hash = utils.compute_hash(
            sorted([ns.hash for ns in template.namespaces]))

        return template
예제 #9
0
    def load(name):
        """Loads a namespace from disk

        :param name: the name of namespace to load.
        :return: a fully configured namespace.
        """

        namespace = Namespace(name)

        saved_conf = cfg.CONF
        cfg.CONF = cfg.ConfigOpts()

        try:
            json_data = validator_generator.generate_ns_data(name)
        finally:
            cfg.CONF = saved_conf

        namespace.hash = utils.compute_hash(json_data)
        namespace.data = json.loads(json_data)

        return namespace
예제 #10
0
파일: agent.py 프로젝트: openstack/congress
    def load(name):
        """Loads a namespace from disk

        :param name: the name of namespace to load.
        :return: a fully configured namespace.
        """

        namespace = Namespace(name)

        saved_conf = cfg.CONF
        cfg.CONF = cfg.ConfigOpts()

        try:
            json_data = validator_generator.generate_ns_data(name)
        finally:
            cfg.CONF = saved_conf

        namespace.hash = utils.compute_hash(json_data)
        namespace.data = json.loads(json_data)

        return namespace
예제 #11
0
def add_namespace(conf, ns_dict, ns_hash):
    """Add options from a kind to an already existing config"""

    for group_name, group in six.iteritems(ns_dict):

        try:
            title = group['object'].get('title', None)
            help_msg = group['object'].get('help', None)
        except AttributeError:
            title = help_msg = None
        cfggroup = make_group(group_name, title, help_msg)

        # Get back the instance already stored or register the group.
        if cfggroup is not None:
            # pylint: disable=protected-access
            cfggroup = conf._get_group(cfggroup, autocreate=True)

        for namespace in group['namespaces']:

            for option in namespace[1]:
                opt_hash = utils.compute_hash(ns_hash, group_name,
                                              option['name'])
                cfgopt = make_opt(option, opt_hash, ns_hash)
                conf.register_opt(cfgopt, cfggroup)
예제 #12
0
def add_namespace(conf, ns_dict, ns_hash):
    """Add options from a kind to an already existing config"""

    for group_name, group in six.iteritems(ns_dict):

        try:
            title = group['object'].get('title', None)
            help_msg = group['object'].get('help', None)
        except AttributeError:
            title = help_msg = None
        cfggroup = make_group(group_name, title, help_msg)

        # Get back the instance already stored or register the group.
        if cfggroup is not None:
            # pylint: disable=protected-access
            cfggroup = conf._get_group(cfggroup, autocreate=True)

        for namespace in group['namespaces']:

            for option in namespace[1]:
                opt_hash = utils.compute_hash(ns_hash, group_name,
                                              option['name'])
                cfgopt = make_opt(option, opt_hash, ns_hash)
                conf.register_opt(cfgopt, cfggroup)
예제 #13
0
 def test_hash(self):
     """Test shape of hash generated"""
     re_hash = ('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-'
                '[0-9a-f]{4}-[0-9a-f]{8}')
     self.assertTrue(re.match(re_hash, utils.compute_hash('foo')))
     self.assertTrue(re.match(re_hash, utils.compute_hash('foo', 'bar')))
예제 #14
0
 def test_hash(self):
     """Test shape of hash generated"""
     re_hash = ('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-'
                '[0-9a-f]{4}-[0-9a-f]{8}')
     self.assertTrue(re.match(re_hash, utils.compute_hash('foo')))
     self.assertTrue(re.match(re_hash, utils.compute_hash('foo', 'bar')))