コード例 #1
0
ファイル: apicommands.py プロジェクト: chbatey/saboteur
def build_add_fault_command(shell, params):
    if not params.has_key('type') or params['type'] not in FAULT_TYPES.keys():
        message = 'must be present and one of ' + str(alphabetical_keys(FAULT_TYPES))
        exception=MultipleInvalid()
        exception.add(Invalid(message, ['type'], message))
        raise exception
    return FAULT_TYPES[params['type']](shell, params)
コード例 #2
0
ファイル: apicommands.py プロジェクト: wontruefree/saboteur
def build_add_fault_command(shell, params):
    if not params.has_key('type') or params['type'] not in FAULT_TYPES.keys():
        message = 'must be present and one of ' + str(
            alphabetical_keys(FAULT_TYPES))
        exception = MultipleInvalid()
        exception.add(Invalid(message, ['type'], message))
        raise exception
    return FAULT_TYPES[params['type']](shell, params)
コード例 #3
0
ファイル: conf.py プロジェクト: mbookman/elasticluster
    def read_config(self):
        """Reads the configuration properties from the ini file and links the
        section to comply with the cluster config dictionary format.

        :return: dictionary containing all configuration properties from the
         ini file in compliance to the cluster config format
        :raises: :py:class:`voluptuous.MultipleInvalid` if not all sections
                 present or broken links between secitons
        """
        clusters = dict((key, value) for key, value in self.conf.iteritems() if
                        re.search(ConfigReader.cluster_section + "/(.*)", key)
                        and key.count("/") == 1)

        conf_values = dict()

        errors = MultipleInvalid()
        # FIXME: to be refactored:
        # we should check independently each one of the sections, and raise errors accordingly.

        for cluster in clusters:
            # Get the name of the cluster
            name = re.search(ConfigReader.cluster_section + "/(.*)",
                             cluster).groups()[0]
            if not name:
                errors.add("Invalid section name `%s`" % cluster)
                continue

            cluster_conf = dict(self.conf[cluster])

            try:
                self.schemas['cluster'](cluster_conf)
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add("Section `%s`: %s" % (cluster, error))
                continue

            cloud_name = ConfigReader.cloud_section + "/" + cluster_conf[
                'cloud']
            login_name = ConfigReader.login_section + "/" + cluster_conf[
                'login']
            setup_name = ConfigReader.setup_section + "/" + cluster_conf[
                'setup_provider']

            values = dict()
            values['cluster'] = cluster_conf
            try:
                values['setup'] = dict(self.conf[setup_name])
                self.schemas['setup'](values['setup'])
            except KeyError, ex:
                errors.add(
                    "cluster `%s` setup section `%s` does not exists" % (
                        cluster, setup_name))
            except MultipleInvalid, ex:
                for error in ex.errors:
                    errors.add(error)
コード例 #4
0
        def check_assertion_consumer_service(attrs):
            keys = attrs.keys()
            if ('AssertionConsumerServiceURL' in keys
                    and 'ProtocolBinding' in keys
                    and 'AssertionConsumerServiceIndex' not in keys):
                _errors = []
                if attrs['ProtocolBinding'] != BINDING_HTTP_POST:
                    _errors.append(
                        Invalid(DEFAULT_VALUE_ERROR.format(BINDING_HTTP_POST),
                                path=['ProtocolBinding']))
                if attrs[
                        'AssertionConsumerServiceURL'] not in assertion_consumer_service_urls:
                    _errors.append(
                        Invalid(DEFAULT_VALUE_ERROR.format(
                            assertion_consumer_service_urls),
                                path=['AssertionConsumerServiceURL']))
                if _errors:
                    raise MultipleInvalid(errors=_errors)
                return attrs

            elif ('AssertionConsumerServiceURL' not in keys
                  and 'ProtocolBinding' not in keys
                  and 'AssertionConsumerServiceIndex' in keys):
                if attrs[
                        'AssertionConsumerServiceIndex'] not in assertion_consumer_service_indexes:
                    raise Invalid(DEFAULT_LIST_VALUE_ERROR.format(
                        ', '.join(assertion_consumer_service_indexes)),
                                  path=['AssertionConsumerServiceIndex'])
                return attrs

            else:
                raise Invalid(
                    'Uno e uno solo uno tra gli attributi o gruppi di attributi devono essere presenti: '
                    '[AssertionConsumerServiceIndex, [AssertionConsumerServiceUrl, ProtocolBinding]]'
                )
コード例 #5
0
    def __call__(self, v):
        if not isinstance(v, (list, tuple)):
            raise Invalid(self.msg or 'Value {} is not sequence!'.format(v))

        if len(v) != len(self._schemas):
            raise Invalid(self.msg or 'List lengths differ, value:{} != target:{}'.format(len(v), len(self._schemas)))

        consumed = set()
        missing = []
        for index, value in enumerate(v):
            found = False
            for i, s in enumerate(self._schemas):
                if i in consumed:
                    continue
                try:
                    s(value)
                except Invalid:
                    pass
                else:
                    found = True
                    consumed.add(i)
                    break
            if not found:
                missing.append((index, value))

        if len(missing) == 1:
            el = missing[0]
            raise Invalid(self.msg or 'Element #{} ({}) is not valid against any validator'.format(el[0], el[1]))
        elif missing:
            raise MultipleInvalid([
                Invalid(self.msg or 'Element #{} ({}) is not valid against any validator'.format(el[0], el[1]))
                for el in missing
            ])
        return v
コード例 #6
0
    def __init__(self, **kargs):
        super(EntityBase, self).__init__(kargs)
        self.validate()

        try:
            raise getattr(self, 'error')
        except AttributeError:
            pass
        except Invalid as e:
            raise MultipleInvalid([e])
コード例 #7
0
 def __call__(self, data):
     """Validate data against this schema."""
     try:
         values = self._compiled([], data)
         if hasattr(self, 'after_validate'):
             return self.after_validate(values)
         return values
     except MultipleInvalid:
         raise
     except Invalid as e:
         raise MultipleInvalid([e])
コード例 #8
0
 def after_validate(self, values):
     errors = []
     for key in values.keys():
         method_name = key + '_validator'
         if hasattr(self, method_name):
             try:
                 getattr(self, method_name)(values)
             except Invalid as e:
                 errors.append(ExclusiveInvalid(e.msg, [key]))
     if errors:
         raise MultipleInvalid(errors)
     return values
コード例 #9
0
def test__validate_owncakeydata_exception(mock_Schema):

    mocked_schema = mock.MagicMock()
    mocked_schema.side_effect = MultipleInvalid("x")
    mock_Schema.return_value = mocked_schema

    with pytest.raises(OnwCAInvalidDataStructure) as err:
        _validate_owncakeydata(
            {
                "key": "key",
                "key_bytes": "key_bytes",
                "public_key": "public_key",
                "public_key_bytes": "public_key_bytes",
            }
        )

        assert "OnwcaKeyData: " in err.value
コード例 #10
0
def _check_certificate(cert):
    _errors = []
    cert = load_certificate(cert)
    is_expired = verify_certificate_expiration(cert)
    has_supported_alg = verify_certificate_algorithm(cert)
    no_sha1 = verify_bad_certificate_algorithm(cert)
    if is_expired:
        _errors.append(Invalid('Il certificato è scaduto.'))
    if not has_supported_alg:
        _errors.append(
            Invalid(
                'Il certificato deve essere firmato con un algoritmo valido.'))
    if not no_sha1:
        _errors.append(
            Invalid(
                'Il certificato non deve essere firmato tramite algoritmo SHA1 (deprecato).'
            ))
    if _errors:
        raise MultipleInvalid(errors=_errors)
    return cert
コード例 #11
0
ファイル: conf.py プロジェクト: riccardomurri/elasticluster
    def read_config(self):
        """Reads the configuration properties from the ini file and links the
        section to comply with the cluster config dictionary format.

        :return: tuple of dictionaries (clusters, storage) containing
         all configuration properties from the ini file in compliance
         to the cluster config format, and global configuration options for the storage.

        :raises: :py:class:`voluptuous.MultipleInvalid` if not all sections
                 present or broken links between secitons

        """
        storage_section = self.conf.get('storage', {
            'storage_path': Configurator.default_storage_path,
            'storage_type': Configurator.default_storage_type})

        clusters = dict((key, value) for key, value in self.conf.iteritems() if
                        re.search(ConfigReader.cluster_section + "/(.*)", key)
                        and key.count("/") == 1)

        conf_values = dict()

        errors = MultipleInvalid()
        # FIXME: to be refactored:
        # we should check independently each one of the sections, and raise errors accordingly.

        for cluster in clusters:
            # Get the name of the cluster
            name = re.search(ConfigReader.cluster_section + "/(.*)",
                             cluster).groups()[0]
            if not name:
                errors.add("Invalid section name `%s`" % cluster)
                continue

            cluster_conf = dict(self.conf[cluster])

            try:
                self.schemas['cluster'](cluster_conf)
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add("Section `%s`: %s" % (cluster, error))
                continue

            cloud_name = ConfigReader.cloud_section + "/" + cluster_conf[
                'cloud']
            login_name = ConfigReader.login_section + "/" + cluster_conf[
                'login']
            setup_name = ConfigReader.setup_section + "/" + cluster_conf[
                'setup_provider']

            values = dict()
            values['cluster'] = cluster_conf
            try:
                values['setup'] = dict(self.conf[setup_name])
                self.schemas['setup'](values['setup'])
            except KeyError as ex:
                errors.add(
                    "cluster `%s` setup section `%s` does not exists" % (
                        cluster, setup_name))
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add(error)

            try:
                values['login'] = dict(self.conf[login_name])
                self.schemas['login'](values['login'])
            except KeyError as ex:
                errors.add(
                    "cluster `%s` login section `%s` does not exists" % (
                        cluster, login_name))
            except MultipleInvalid as ex:
                errors.add(Invalid("Error in login section `%s`: %s" % (
                    login_name, str.join(', ', [str(e) for e in ex.errors]))))

            try:
                values['cloud'] = dict(self.conf[cloud_name])
                self.schemas['cloud'](values['cloud'])
            except KeyError as ex:
                errors.add(
                    "cluster `%s` cloud section `%s` does not exists" % (
                        cluster, cloud_name))
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add(Invalid("section %s: %s" % (cloud_name, error)))

            try:
                # nodes can inherit the properties of cluster or overwrite them
                nodes = dict((key, value) for key, value in
                             values['cluster'].items() if
                             key.endswith('_nodes'))
                values['nodes'] = dict()
                for node in nodes.iterkeys():
                    node_name = re.search("(.*)_nodes", node).groups()[0]
                    property_name = "%s/%s/%s" % (ConfigReader.cluster_section,
                                                  name, node_name)
                    if property_name in self.conf:
                        node_values = dict(
                            (key, value.strip("'").strip('"')) for key, value
                            in self.conf[property_name].iteritems())
                        node_values = dict(
                            values['cluster'].items() + node_values.items())
                        values['nodes'][node_name] = node_values
                    else:
                        values['nodes'][node_name] = values['cluster']

                if errors.errors:
                    log.error("Ignoring cluster `%s`: %s" % (
                        name, str.join(", ", [str(e) for e in errors.errors])))
                else:
                    conf_values[name] = values
            except KeyError as ex:
                errors.add("Error in section `%s`" % cluster)

        # FIXME: do we really need to raise an exception if we cannot
        # parse *part* of the configuration files? We should just
        # ignore those with errors and return both the parsed
        # configuration values _and_ a list of errors
        if errors.errors:
            raise errors
        return (conf_values, storage_section)
コード例 #12
0
ファイル: conf.py プロジェクト: sternshus/elasticluster
    def read_config(self):
        """Reads the configuration properties from the ini file and links the
        section to comply with the cluster config dictionary format.

        :return: tuple of dictionaries (clusters, storage) containing
         all configuration properties from the ini file in compliance
         to the cluster config format, and global configuration options for the storage.

        :raises: :py:class:`voluptuous.MultipleInvalid` if not all sections
                 present or broken links between secitons

        """
        storage_section = self.conf.get(
            'storage', {
                'storage_path': Configurator.default_storage_path,
                'storage_type': Configurator.default_storage_type
            })

        clusters = dict((key, value) for key, value in self.conf.items()
                        if re.search(ConfigReader.cluster_section +
                                     "/(.*)", key) and key.count("/") == 1)

        conf_values = dict()

        errors = MultipleInvalid()
        # FIXME: to be refactored:
        # we should check independently each one of the sections, and raise errors accordingly.

        for cluster in clusters:
            # Get the name of the cluster
            name = re.search(ConfigReader.cluster_section + "/(.*)",
                             cluster).groups()[0]
            if not name:
                errors.add("Invalid section name `%s`" % cluster)
                continue

            cluster_conf = dict(self.conf[cluster])

            try:
                self.schemas['cluster'](cluster_conf)
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add("Section `%s`: %s" % (cluster, error))
                continue

            cloud_name = ConfigReader.cloud_section + "/" + cluster_conf[
                'cloud']
            login_name = ConfigReader.login_section + "/" + cluster_conf[
                'login']
            setup_name = ConfigReader.setup_section + "/" + cluster_conf[
                'setup_provider']

            values = dict()
            values['cluster'] = cluster_conf
            try:
                values['setup'] = dict(self.conf[setup_name])
                self.schemas['setup'](values['setup'])
            except KeyError as ex:
                errors.add("cluster `%s` setup section `%s` does not exists" %
                           (cluster, setup_name))
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add(error)

            try:
                values['login'] = dict(self.conf[login_name])
                self.schemas['login'](values['login'])
            except KeyError as ex:
                errors.add("cluster `%s` login section `%s` does not exists" %
                           (cluster, login_name))
            except MultipleInvalid as ex:
                errors.add(
                    Invalid("Error in login section `%s`: %s" %
                            (login_name,
                             str.join(', ', [str(e) for e in ex.errors]))))

            try:
                values['cloud'] = dict(self.conf[cloud_name])
                self.schemas['cloud'](values['cloud'])
            except KeyError as ex:
                errors.add("cluster `%s` cloud section `%s` does not exists" %
                           (cluster, cloud_name))
            except MultipleInvalid as ex:
                for error in ex.errors:
                    errors.add(Invalid("section %s: %s" % (cloud_name, error)))

            try:
                # nodes can inherit the properties of cluster or overwrite them
                nodes = dict((key, value)
                             for key, value in values['cluster'].items()
                             if key.endswith('_nodes'))
                values['nodes'] = dict()
                for node in nodes.keys():
                    node_name = re.search("(.*)_nodes", node).groups()[0]
                    property_name = "%s/%s/%s" % (ConfigReader.cluster_section,
                                                  name, node_name)
                    if property_name in self.conf:
                        node_values = dict(
                            (key, value.strip("'").strip('"'))
                            for key, value in self.conf[property_name].items())
                        node_values = dict(values['cluster'].items() +
                                           node_values.items())
                        values['nodes'][node_name] = node_values
                    else:
                        values['nodes'][node_name] = values['cluster']

                if errors.errors:
                    log.error(
                        "Ignoring cluster `%s`: %s" %
                        (name, str.join(", ", [str(e)
                                               for e in errors.errors])))
                else:
                    conf_values[name] = values
            except KeyError as ex:
                errors.add("Error in section `%s`" % cluster)

        # FIXME: do we really need to raise an exception if we cannot
        # parse *part* of the configuration files? We should just
        # ignore those with errors and return both the parsed
        # configuration values _and_ a list of errors
        if errors.errors:
            raise errors
        return (conf_values, storage_section)
コード例 #13
0
def server_file_structure(data: dict) -> ServerFileData:
    """"Transform read data into the elegant form, validating extra things"""

    errs = []

    # Deal with servers
    servers = data['servers']
    server_ids = servers.values()

    # Deal with servers
    # NB: this is a dict input; server names are definitely unique

    servers_output: Dict[str, Server] = {
        k: Server(k, v) for k, v in servers.items()
    }

    # Deal with switches
    # NB: this is a dict input; switchnames are definitely unique

    switches = data['switches']
    switch_ids = switches.values()

    switches_output: Dict[str, Switch] = {
        k: Switch(k, v) for k, v in switches.items()
    }

    # Make device set from servers and switches

    devices_output: Dict[str, Device] = dict(servers_output)
    devices_output.update(switches_output)

    if len(servers) + len(switches) != len(devices_output.keys()):
        errs.append(Invalid("Server shares a name with a switch"))

    all_ids = list(server_ids)
    all_ids.extend(switch_ids)

    if len(server_ids) + len(switch_ids) != len(set(all_ids)):
        errs.append(Invalid(
            f"Server [{str(sorted(server_ids))}] "
            f"and switch [{str(sorted(switch_ids))}] "
            f"serial numbers are not unique"))

    try:
        # Construct racks

        racks = data['racks']

        racks_output: Dict[str, Rack] = {}

        for rack_name, elems in racks.items():
            rack_elems: Dict[int, Device] = {}
            for loc, dev_name in elems.items():
                dev_obj = devices_output.get(dev_name)
                if dev_obj is None:
                    errs.append(
                        Invalid(
                            f"Rack {rack_name} location {loc}: "
                            f"{dev_name} is an unknown device"))
                else:
                    rack_elems[loc] = dev_obj

            racks_output[rack_name] = Rack(dev_name, rack_elems)

        connections = data['connections']

        connections_output: Set[Connection] = set()
        # Confirm we're connecting devices that we know about.
        # Transform connections to device references.

        for rack_name, wires in connections.items():
            rack = racks_output.get(rack_name)
            if rack is None:
                errs.append(Invalid(f'In connections, {rack_name} '
                                    f'has not been defined'))
            else:
                # Sort: gets consistent error ordering.
                for f in sorted(wires):
                    rack_slot1, port1, rack_slot2, port2 = f

                    def get_dev(loc: int) -> Optional[Device]:
                        assert rack is not None  # for typechecking
                        dev = rack.devices.get(loc)
                        if dev is None:
                            errs.append(
                                Invalid(
                                    f'In connections, RU #{loc} '
                                    f'in {rack_name} has no device'))
                        return dev

                    rack_dev1 = get_dev(rack_slot1)
                    rack_dev2 = get_dev(rack_slot2)

                    if rack_dev1 is not None and rack_dev2 is not None:
                        conn = Connection(rack_dev1, port1,
                                          rack_dev2, port2)
                        if conn in connections_output:
                            errs.append(
                                Invalid(
                                    f"Duplicate connection: "
                                    f"slot#{rack_slot1}:port#{port1} "
                                    f"-> slot#{rack_slot2}:port#{port2} "
                                    f"results in {conn.text()} - "
                                    "do you have the reverse "
                                    "connection listed?"))
                        else:
                            connections_output.add(conn)

    except Exception as e:
        import traceback
        traceback.print_exc()
        raise

    if errs:
        raise MultipleInvalid(errs)

    return ServerFileData(
        servers_output,
        switches_output,
        devices_output,
        racks_output,
        connections_output)