Пример #1
0
    def neutron_check_segmentation_ids(self):
        """1. check networks VLAN IDs not in Neutron L2 private VLAN ID range
        for VLAN segmentation only
        2. check networks VLAN IDs should not intersect
        (neutron)
        """
        tagged_nets = dict((n["name"], n["vlan_start"]) for n in filter(
            lambda n: (n["vlan_start"] is not None), self.networks))

        if tagged_nets:
            if self.task.cluster.network_config.segmentation_type == \
                    consts.NEUTRON_SEGMENT_TYPES.vlan:
                # check networks tags not in Neutron L2 private VLAN ID range
                vrange = self.network_config['vlan_range']
                net_intersect = [name for name, vlan in tagged_nets.iteritems()
                                 if vrange[0] <= vlan <= vrange[1]]
                if net_intersect:
                    nets_with_errors = ", ". \
                        join(net_intersect)
                    err_msg = u"VLAN tags of {0} network(s) intersect with " \
                              u"VLAN ID range defined for Neutron L2. " \
                              u"Networks VLAN tags must not intersect " \
                              u"with Neutron L2 VLAN ID range.". \
                        format(nets_with_errors)
                    raise errors.NetworkCheckError(err_msg)

            # check networks VLAN IDs should not intersect
            net_intersect = [name for name, vlan in tagged_nets.iteritems()
                             if tagged_nets.values().count(vlan) >= 2]
            if net_intersect:
                err_msg = u"{0} networks use the same VLAN tags. " \
                          u"You should assign different VLAN tag " \
                          u"to every network.".format(", ".join(net_intersect))
                raise errors.NetworkCheckError(err_msg)
Пример #2
0
 def expose_network_check_error_messages(task, result, err_messages):
     if err_messages:
         task.result = result
         db().add(task)
         db().commit()
         full_err_msg = u"\n".join(err_messages)
         raise errors.NetworkCheckError(full_err_msg)
Пример #3
0
    def __init__(self, task, data):
        """Collect Network Groups data
        """
        self.cluster = task.cluster
        self.task = task
        self.data = data
        self.net_man = self.cluster.network_manager()
        self.net_provider = self.cluster.net_provider
        admin_ng = self.net_man.get_admin_network_group()
        fields = NetworkGroup.__mapper__.columns.keys()
        net = NetworkConfigurationSerializer.serialize_network_group(
            admin_ng, fields)
        # change Admin name for UI
        net.update(name='admin (PXE)')
        self.networks = [net]
        for ng in self.cluster.network_groups:
            net = NetworkConfigurationSerializer.serialize_network_group(
                ng, fields)
            self.networks.append(net)
        # merge with data['networks']
        if 'networks' in data:
            for data_net in data['networks']:
                for net in self.networks:
                    if data_net['id'] == net['id']:
                        net.update(data_net)
                        break
                else:
                    raise errors.NetworkCheckError(
                        u"Invalid network ID: {0}".format(data_net['id']),
                        add_client=False)

        self.result = []
        self.err_msgs = []
Пример #4
0
    def neutron_check_segmentation_ids(self):
        """Check neutron segmentation ids

        check networks VLAN IDs not in Neutron L2 private VLAN ID range
        for VLAN segmentation only
        (neutron)
        """
        tagged_nets = dict((n["name"], n["vlan_start"]) for n in filter(
            lambda n: (n["vlan_start"] is not None), self.networks))

        if tagged_nets:
            if self.task.cluster.network_config.segmentation_type == \
                    consts.NEUTRON_SEGMENT_TYPES.vlan:
                # check networks tags not in Neutron L2 private VLAN ID range
                vrange = self.network_config['vlan_range']
                net_intersect = [
                    name for name, vlan in tagged_nets.iteritems()
                    if vrange[0] <= vlan <= vrange[1]
                ]
                if net_intersect:
                    nets_with_errors = ", ". \
                        join(net_intersect)
                    err_msg = u"VLAN tags of {0} network(s) intersect with " \
                              u"VLAN ID range defined for Neutron L2. " \
                              u"Networks VLAN tags must not intersect " \
                              u"with Neutron L2 VLAN ID range.". \
                        format(nets_with_errors)
                    raise errors.NetworkCheckError(err_msg)
Пример #5
0
    def _check_public_network(cls, task):
        all_public = \
            objects.Cluster.should_assign_public_to_all_nodes(task.cluster)

        public_networks = filter(
            lambda ng: ng.name == 'public',
            task.cluster.network_groups)

        for public in public_networks:
            nodes = objects.NodeCollection.get_by_group_id(public.group_id)
            if all_public:
                nodes_count = nodes.count()
            else:
                nodes_count = sum(int(objects.Node.should_have_public(node))
                                  for node in nodes)
            vip_count = 0
            if task.cluster.is_ha_mode and (
                any('controller' in node.all_roles
                    for node in nodes)
            ):
                # 2 IPs are required for VIPs (1 for haproxy + 1 for vrouter)
                vip_count = 2
            if cls.__network_size(public) < nodes_count + vip_count:
                error_message = cls.__format_network_error(public, nodes_count)
                raise errors.NetworkCheckError(error_message)
Пример #6
0
    def neutron_check_segmentation_ids(self):
        """1. check networks VLAN IDs not in Neutron L2 private VLAN ID range
        for VLAN segmentation only
        2. check networks VLAN IDs should not intersect
        (neutron)
        """
        tagged_nets = dict((n["name"], n["vlan_start"]) for n in filter(
            lambda n: (n["vlan_start"] is not None), self.networks))

        if tagged_nets:
            if self.task.cluster.net_segment_type == 'vlan':
                # check networks tags not in Neutron L2 private VLAN ID range
                if 'neutron_parameters' in self.data:
                    l2cfg = self.data['neutron_parameters']['L2']
                else:
                    l2cfg = self.task.cluster.neutron_config.L2
                for net, net_conf in l2cfg['phys_nets'].iteritems():
                    vrange = net_conf['vlan_range']
                    if vrange:
                        break
                else:
                    err_msg = u"Wrong VLAN range for Neutron L2.\n"
                    raise errors.NetworkCheckError(err_msg)

                net_intersect = [name for name, vlan in tagged_nets.iteritems()
                                 if vrange[0] <= vlan <= vrange[1]]
                if net_intersect:
                    nets_with_errors = ", ". \
                        join(net_intersect)
                    err_msg = u"VLAN tags of {0} network(s) intersect with " \
                              u"VLAN ID range defined for Neutron L2. " \
                              u"Networks VLAN tags must not intersect " \
                              u"with Neutron L2 VLAN ID range.". \
                        format(nets_with_errors)
                    raise errors.NetworkCheckError(err_msg)

            # check networks VLAN IDs should not intersect
            net_intersect = [name for name, vlan in tagged_nets.iteritems()
                             if tagged_nets.values().count(vlan) >= 2]
            if net_intersect:
                err_msg = u"{0} networks use the same VLAN tags. " \
                          u"You should assign different VLAN tag " \
                          u"to every network.".format(", ".join(net_intersect))
                raise errors.NetworkCheckError(err_msg)
Пример #7
0
    def __check_network(cls, task):
        nodes_count = len(task.cluster.nodes)

        public_network = filter(lambda ng: ng.name == 'public',
                                task.cluster.network_groups)[0]
        public_network_size = cls.__network_size(public_network)

        if public_network_size < nodes_count:
            error_message = cls.__format_network_error(nodes_count)
            raise errors.NetworkCheckError(error_message)
Пример #8
0
    def __init__(self, task, data):
        """Collect Network Groups data
        """
        self.cluster = task.cluster
        self.task = task
        self.data = data
        self.net_man = objects.Cluster.get_network_manager(self.cluster)
        #NetworkManager,NeutronManager,NovaNetworkManager
        self.net_provider = self.cluster.net_provider
        #net_provider列的值(枚举)
        admin_ng = self.net_man.get_admin_network_group()
        #1.admin_ngs = db().query(NetworkGroup).filter_by(name="fuelweb_admin")
        #2.admin_ng = admin_ng or admin_ngs.filter_by(group_id=None).first()
        fields = NetworkGroup.__mapper__.columns.keys() + ['meta']
        net = NetworkConfigurationSerializer.serialize_network_group(admin_ng,
                                                                     fields)
        # change Admin name for UI
        net.update(name='admin (PXE)')
        self.networks = [net]
        for ng in self.cluster.network_groups:
            net = NetworkConfigurationSerializer.serialize_network_group(
                ng,
                fields)
            self.networks.append(net)
        # merge with data['networks']
        logger.info(data)
        if 'networks' in data:
            for data_net in data['networks']:
                for net in self.networks:
                    if data_net['id'] == net['id']:
                        if data_net.get('meta'):
                            data_net.pop('meta')
                        net.update(data_net)
                        if data_net.get('name') == 'fuelweb_admin':
                            net.update(name='admin (PXE)')
                        break
                else:
                    raise errors.NetworkCheckError(
                        u"Invalid network ID: {0}".format(data_net['id']))
        # get common networking parameters
        serializer = {'neutron': NeutronNetworkConfigurationSerializer,
                      'nova_network': NovaNetworkConfigurationSerializer}
        self.network_config = serializer[self.net_provider].\
            serialize_network_params(self.cluster)
        self.network_config.update(data.get('networking_parameters', {}))

        self.result = []
        self.err_msgs = []
Пример #9
0
    def check_vlan_ids_intersection(self):
        """Networks VLAN IDs should not intersect for any node's interface."""
        if self.cluster.network_config.configuration_template is not None:
            # TODO(akasatkin) checking of network templates to be considered
            return

        tagged_nets = dict((n["id"], n["vlan_start"]) for n in filter(
            lambda n: (n["vlan_start"] is not None), self.networks))

        # nothing to check
        if len(tagged_nets) < 2:
            return

        nodes_networks = \
            objects.Cluster.get_networks_to_interfaces_mapping_on_all_nodes(
                self.cluster)

        # first, group by hostname
        for node_name, data in groupby(nodes_networks, lambda x: x[0]):
            # then group by interface name for particular node
            for if_name, nic_nets in groupby(data, lambda x: x[1]):
                net_ids = [
                    net_id for _, _, net_id in nic_nets
                    if net_id in tagged_nets
                ]
                if len(net_ids) < 2:
                    # no more than 1 tagged network is on the interface
                    continue
                vlan_ids = [tagged_nets[n] for n in net_ids]
                if len(set(vlan_ids)) < len(vlan_ids):
                    # some VLAN IDs are not unique for this interface
                    seen_vlan_ids = set()
                    duplicate_net_ids = set()
                    for idx in range(len(vlan_ids)):
                        if vlan_ids[idx] in seen_vlan_ids:
                            duplicate_net_ids.add(net_ids[idx])
                        seen_vlan_ids.add(vlan_ids[idx])
                    net_names = [
                        net['name'] for net in self.networks
                        if net['id'] in duplicate_net_ids
                    ]

                    err_msg = u"Node {0}, interface {1}: {2} networks use " \
                        u"the same VLAN tags. Different VLAN tags should be " \
                        u"assigned to the networks on the same interface.".\
                        format(node_name, if_name, ", ".join(net_names))
                    raise errors.NetworkCheckError(err_msg)
Пример #10
0
    def neutron_check_interface_mapping(self):
        """Check mapping of networks to NICs (Neutron)
        """
        # check untagged networks intersection
        untagged_nets = set(
            n["id"] for n in filter(
                lambda n: (n['vlan_start'] is None) and
                          (not n['meta'].get('neutron_vlan_range')),
                self.networks))
        if untagged_nets:
            logger.info(
                "Untagged networks found, "
                "checking intersection between them...")
            interfaces = []
            for node in self.cluster.nodes:
                for iface in node.interfaces:
                    interfaces.append(iface)
            found_intersection = []

            for iface in interfaces:
                nets = dict(
                    (n.id, n.name)
                    for n in iface.assigned_networks_list)

                crossed_nets = set(nets.keys()) & untagged_nets
                if len(crossed_nets) > 1:
                    err_net_names = [
                        '"{0}"'.format(nets[i]) for i in crossed_nets]
                    found_intersection.append(
                        [iface.node.name, err_net_names])

            if found_intersection:
                nodes_with_errors = [
                    u'Node "{0}": {1}'.format(
                        name,
                        ", ".join(_networks)
                    ) for name, _networks in found_intersection]
                err_msg = u"Some untagged networks are " \
                          "assigned to the same physical interface. " \
                          "You should assign them to " \
                          "different physical interfaces:\n{0}". \
                    format("\n".join(nodes_with_errors))
                raise errors.NetworkCheckError(err_msg)
Пример #11
0
    def neutron_check_interface_mapping(self):

        # check if there any networks
        # on the same interface as admin network (main)
        admin_interfaces = map(lambda node: node.admin_interface,
                               self.cluster.nodes)
        found_intersection = []

        all_roles = set(
            [n["id"] for n in self.networks if n != self.networks[0]])
        for iface in admin_interfaces:
            nets = dict((n.id, n.name) for n in iface.assigned_networks)

            err_nets = set(nets.keys()) & all_roles
            if err_nets:
                err_net_names = ['"{0}"'.format(nets[i]) for i in err_nets]
                found_intersection.append([iface.node.name, err_net_names])

        if found_intersection:
            nodes_with_errors = [
                u'Node "{0}": {1}'.format(name, ", ".join(_networks))
                for name, _networks in found_intersection
            ]
            err_msg = u"Some networks are " \
                      "assigned to the same physical interface as " \
                      "admin (PXE) network. You should move them to " \
                      "another physical interfaces:\n{0}". \
                format("\n".join(nodes_with_errors))
            raise errors.NetworkCheckError(err_msg, add_client=False)

        # check if there any networks
        # on the same interface as private network (for vlan)
        if self.cluster.net_segment_type == 'vlan':
            private_interfaces = []
            # there should be shorter method to do this !
            for node in self.cluster.nodes:
                for iface in node.interfaces:
                    for anet in iface.assigned_networks:
                        if anet.name == 'private':
                            private_interfaces.append(iface)
            found_intersection = []

            all_roles = set(n["id"] for n in self.networks
                            if n["name"] != 'private')
            for iface in private_interfaces:
                nets = dict((n.id, n.name) for n in iface.assigned_networks)

                err_nets = set(nets.keys()) & all_roles
                if err_nets:
                    err_net_names = ['"{0}"'.format(nets[i]) for i in err_nets]
                    found_intersection.append([iface.node.name, err_net_names])

            if found_intersection:
                nodes_with_errors = [
                    u'Node "{0}": {1}'.format(name, ", ".join(_networks))
                    for name, _networks in found_intersection
                ]
                err_msg = u"Some networks are " \
                          "assigned to the same physical interface as " \
                          "private network. You should move them to " \
                          "another physical interfaces:\n{0}". \
                    format("\n".join(nodes_with_errors))
                raise errors.NetworkCheckError(err_msg, add_client=False)

        # check untagged networks intersection
        untagged_nets = set(n["id"] for n in filter(
            lambda n: (n["vlan_start"] is None), self.networks))
        if untagged_nets:
            logger.info("Untagged networks found, "
                        "checking intersection between them...")
            interfaces = []
            for node in self.cluster.nodes:
                for iface in node.interfaces:
                    interfaces.append(iface)
            found_intersection = []

            for iface in interfaces:
                nets = dict((n.id, n.name) for n in iface.assigned_networks)

                crossed_nets = set(nets.keys()) & untagged_nets
                if len(crossed_nets) > 1:
                    err_net_names = [
                        '"{0}"'.format(nets[i]) for i in crossed_nets
                    ]
                    found_intersection.append([iface.node.name, err_net_names])

            if found_intersection:
                nodes_with_errors = [
                    u'Node "{0}": {1}'.format(name, ", ".join(_networks))
                    for name, _networks in found_intersection
                ]
                err_msg = u"Some untagged networks are " \
                          "assigned to the same physical interface. " \
                          "You should assign them to " \
                          "different physical interfaces:\n{0}". \
                    format("\n".join(nodes_with_errors))
                raise errors.NetworkCheckError(err_msg, add_client=False)
Пример #12
0
    def neutron_check_config(self):

        # check: networks VLAN IDs should not be in
        # Neutron L2 private VLAN ID range (VLAN segmentation only)
        tagged_nets = dict((n["name"], n["vlan_start"]) for n in filter(
            lambda n: (n["vlan_start"] is not None), self.networks))

        if tagged_nets:
            if self.cluster.net_segment_type == 'vlan':
                if 'neutron_parameters' in self.data:
                    l2cfg = self.data['neutron_parameters']['L2']
                else:
                    l2cfg = self.cluster.neutron_config.L2
                for net, net_conf in l2cfg['phys_nets'].iteritems():
                    vrange = net_conf['vlan_range']
                    if vrange:
                        break
                else:
                    err_msg = u"Wrong VLAN range.\n"
                    raise errors.NetworkCheckError(err_msg, add_client=False)

                net_intersect = [
                    name for name, vlan in tagged_nets.iteritems()
                    if vrange[0] <= vlan <= vrange[1]
                ]
                if net_intersect:
                    nets_with_errors = ", ". \
                        join(net_intersect)
                    err_msg = u"Networks VLAN tags are in " \
                              "ID range defined for Neutron L2. " \
                              "You should assign VLAN tags that are " \
                              "not in Neutron L2 VLAN ID range:\n{0}". \
                        format(nets_with_errors)
                    raise errors.NetworkCheckError(err_msg, add_client=False)

            # check: networks VLAN IDs should not intersect
            net_intersect = [
                name for name, vlan in tagged_nets.iteritems()
                if tagged_nets.values().count(vlan) >= 2
            ]
            if net_intersect:
                nets_with_errors = ", ". \
                    join(net_intersect)
                err_msg = u"Some networks use the same VLAN tags. " \
                          "You should assign different VLAN tag " \
                          "to every network:\n{0}". \
                    format(nets_with_errors)
                raise errors.NetworkCheckError(err_msg, add_client=False)

        # check intersection of address ranges
        # between admin networks and all other networks
        admin_ng = self.net_man.get_admin_network_group()
        admin_range = netaddr.IPNetwork(admin_ng.cidr)
        for ng in self.networks[1:]:
            net_errors = []
            sub_ranges = []
            ng_db = db().query(NetworkGroup).get(ng['id'])
            if not ng_db:
                net_errors.append("id")
                self.err_msgs.append("Invalid network ID: {0}".format(
                    ng['id']))
            else:
                if ng.get('cidr'):
                    fnet = netaddr.IPNetwork(ng['cidr'])
                    if self.net_man.is_range_intersection(fnet, admin_range):
                        net_errors.append("cidr")
                        self.err_msgs.append(u"Intersection with admin "
                                             "network(s) '{0}' found".format(
                                                 admin_ng.cidr))
                    # ng['amount'] is always equal 1 for Neutron
                    if fnet.size < ng['network_size']:  # * ng['amount']:
                        net_errors.append("cidr")
                        self.err_msgs.append(u"CIDR size for network '{0}' "
                                             "is less than required".format(
                                                 ng.get('name') or ng_db.name
                                                 or ng_db.id))
                # Check for intersection with Admin network
                if 'ip_ranges' in ng:
                    for k, v in enumerate(ng['ip_ranges']):
                        ip_range = netaddr.IPRange(v[0], v[1])
                        if self.net_man.is_range_intersection(
                                admin_range, ip_range):
                            net_errors.append("cidr")
                            self.err_msgs.append(
                                u"IP range {0} - {1} in {2} network intersects"
                                " with admin range of {3}".format(
                                    v[0], v[1],
                                    ng.get('name') or ng_db.name or ng_db.id,
                                    admin_ng.cidr))
                            sub_ranges.append(k)
            if net_errors:
                self.result.append({
                    "id": int(ng["id"]),
                    "range_errors": sub_ranges,
                    "errors": net_errors
                })
        self.expose_error_messages()

        # check intersection of address ranges
        # between networks except admin network
        ng_names = dict((ng['id'], ng['name']) for ng in self.networks)
        ngs = list(self.networks)
        for ng1 in self.networks:
            net_errors = []
            ngs.remove(ng1)
            for ng2 in ngs:
                if ng1.get('cidr') and ng2.get('cidr'):
                    cidr1 = netaddr.IPNetwork(ng1['cidr'])
                    cidr2 = netaddr.IPNetwork(ng2['cidr'])
                    if self.net_man.is_cidr_intersection(cidr1, cidr2):
                        net_errors.append("cidr")
                        self.err_msgs.append(
                            u"Intersection between network address "
                            "spaces found:\n{0}".format(", ".join(
                                [ng_names[ng1['id']], ng_names[ng2['id']]])))
            if net_errors:
                self.result.append({
                    "id": int(ng1["id"]),
                    "errors": net_errors
                })
        self.expose_error_messages()

        # check Public gateway, Floating Start and Stop IPs
        # belong to Public CIDR
        if 'neutron_parameters' in self.data:
            pre_net = self.data['neutron_parameters']['predefined_networks']
        else:
            pre_net = self.cluster.neutron_config.predefined_networks
        public = [n for n in self.networks if n['name'] == 'public'][0]
        net_errors = []
        fl_range = pre_net['net04_ext']['L3']['floating']
        if public.get('cidr') and public.get('gateway'):
            cidr = netaddr.IPNetwork(public['cidr'])
            if netaddr.IPAddress(public['gateway']) not in cidr:
                net_errors.append("gateway")
                self.err_msgs.append(u"Public gateway {0} is not in Public "
                                     "address space {1}.".format(
                                         public['gateway'], public['cidr']))
            if netaddr.IPRange(fl_range[0], fl_range[1]) not in cidr:
                net_errors.append("float_range")
                self.err_msgs.append(
                    u"Floating address range {0}:{1} is not in Public "
                    "address space {2}.".format(netaddr.IPAddress(fl_range[0]),
                                                netaddr.IPAddress(fl_range[1]),
                                                public['cidr']))
        else:
            net_errors.append("format")
            self.err_msgs.append(
                u"Public gateway or CIDR specification is invalid.")
        self.result = {"id": int(public["id"]), "errors": net_errors}
        self.expose_error_messages()

        # check internal Gateway is in Internal CIDR
        internal = pre_net['net04']['L3']
        if internal.get('cidr') and internal.get('gateway'):
            cidr = netaddr.IPNetwork(internal['cidr'])
            if netaddr.IPAddress(internal['gateway']) not in cidr:
                net_errors.append("gateway")
                self.err_msgs.append(
                    u"Internal gateway {0} is not in Internal "
                    "address space {1}.".format(internal['gateway'],
                                                internal['cidr']))
            if self.net_man.is_range_intersection(
                    netaddr.IPRange(fl_range[0], fl_range[1]), cidr):
                net_errors.append("cidr")
                self.err_msgs.append(
                    u"Intersection between Internal CIDR and Floating range.")
        else:
            net_errors.append("format")
            self.err_msgs.append(
                u"Internal gateway or CIDR specification is invalid.")
        self.result = {"name": "internal", "errors": net_errors}
        self.expose_error_messages()
Пример #13
0
    def execute(self, task, data, check_admin_untagged=False):
        # If not set in data then fetch from db
        if 'net_manager' in data:
            netmanager = data['net_manager']
        else:
            netmanager = task.cluster.net_manager

        if 'networks' in data:
            networks = data['networks']
        else:
            networks = map(lambda x: x.__dict__, task.cluster.network_groups)

        result = []
        err_msgs = []

        if check_admin_untagged:
            # checking if there are untagged networks on the same interface
            # (main) as admin network
            untagged_nets = set(
                n["id"]
                for n in filter(lambda n: (n["vlan_start"] is None), networks))
            if untagged_nets:
                logger.info("Untagged networks found, "
                            "checking admin network intersection...")
                main_ifaces = (db().query(NodeNICInterface).get(
                    NetworkManager().get_main_nic(n.id))
                               for n in task.cluster.nodes)

                found_intersection = []

                for iface in main_ifaces:
                    nets = dict(
                        (n.id, n.name) for n in iface.assigned_networks)
                    err_nets = set(nets.keys()) & untagged_nets
                    if err_nets:
                        err_net_names = [
                            '"{0}"'.format(nets[i]) for i in err_nets
                        ]
                        found_intersection.append(
                            [iface.node.name, err_net_names])

                if found_intersection:
                    nodes_with_errors = [
                        u'Node "{0}": {1}'.format(name, ", ".join(_networks))
                        for name, _networks in found_intersection
                    ]
                    err_msg = u"Some untagged networks are " \
                              "assigned to the same physical interface as " \
                              "admin (PXE) network. You can whether turn " \
                              "on tagging for these OpenStack " \
                              "networks or move them to another physical " \
                              "interface:\n{0}".format("\n".join(
                                  nodes_with_errors
                              ))
                    raise errors.NetworkCheckError(err_msg, add_client=False)

        admin_ng = NetworkManager().get_admin_network_group()
        admin_range = netaddr.IPNetwork(admin_ng.cidr)
        for ng in networks:
            net_errors = []
            sub_ranges = []
            ng_db = db().query(NetworkGroup).get(ng['id'])
            if not ng_db:
                net_errors.append("id")
                err_msgs.append("Invalid network ID: {0}".format(ng['id']))
            else:
                if 'cidr' in ng:
                    fnet = netaddr.IPNetwork(ng['cidr'])
                    if NetworkManager().is_range_in_cidr(fnet, admin_range):
                        net_errors.append("cidr")
                        err_msgs.append("Intersection with admin "
                                        "network(s) '{0}' found".format(
                                            admin_ng.cidr))
                    if fnet.size < ng['network_size'] * ng['amount']:
                        net_errors.append("cidr")
                        err_msgs.append("CIDR size for network '{0}' "
                                        "is less than required".format(
                                            ng.get('name') or ng_db.name
                                            or ng_db.id))
                # Check for intersection with Admin network
                if 'ip_ranges' in ng:
                    for k, v in enumerate(ng['ip_ranges']):
                        ip_range = netaddr.IPRange(v[0], v[1])
                        if NetworkManager().is_range_in_cidr(
                                admin_range, ip_range):
                            net_errors.append("cidr")
                            err_msgs.append(
                                "IP range {0} - {1} in {2} network intersects "
                                "with admin range of {3}".format(
                                    v[0], v[1],
                                    ng.get('name') or ng_db.name or ng_db.id,
                                    admin_ng.cidr))
                            sub_ranges.append(k)

                if ng.get('amount') > 1 and netmanager == 'FlatDHCPManager':
                    net_errors.append("amount")
                    err_msgs.append("Network amount for '{0}' is more than 1 "
                                    "while using FlatDHCP manager.".format(
                                        ng.get('name') or ng_db.name
                                        or ng_db.id))
            if net_errors:
                result.append({
                    "id": int(ng["id"]),
                    "range_errors": sub_ranges,
                    "errors": net_errors
                })
        if err_msgs:
            task.result = result
            db().add(task)
            db().commit()
            full_err_msg = "\n".join(err_msgs)
            raise errors.NetworkCheckError(full_err_msg)
Пример #14
0
    def execute(self, task, data):
        task_uuid = task.uuid

        # If not set in data then fetch from db
        if 'net_manager' in data:
            netmanager = data['net_manager']
        else:
            netmanager = task.cluster.net_manager

        if 'networks' in data:
            networks = data['networks']
        else:
            networks = map(lambda x: x.__dict__, task.cluster.network_groups)

        result = []
        err_msgs = []
        for ng in networks:
            net_errors = []
            ng_db = orm().query(NetworkGroup).get(ng['id'])
            if not ng_db:
                net_errors.append("id")
                err_msgs.append("Invalid network ID: {0}".format(ng['id']))
            else:
                if 'cidr' in ng:
                    fnet = netaddr.IPSet([ng['cidr']])

                    if fnet & netaddr.IPSet(settings.NET_EXCLUDE):
                        net_errors.append("cidr")
                        err_msgs.append(
                            "Intersection with admin "
                            "network(s) '{0}' found".format(
                                settings.NET_EXCLUDE
                            )
                        )
                    if fnet.size < ng['network_size'] * ng['amount']:
                        net_errors.append("cidr")
                        err_msgs.append(
                            "CIDR size for network '{0}' "
                            "is less than required".format(
                                ng.get('name') or ng_db.name or ng_db.id
                            )
                        )
                if ng.get('amount') > 1 and netmanager == 'FlatDHCPManager':
                    net_errors.append("amount")
                    err_msgs.append(
                        "Network amount for '{0}' is more than 1 "
                        "while using FlatDHCP manager.".format(
                            ng.get('name') or ng_db.name or ng_db.id
                        )
                    )
            if net_errors:
                result.append({
                    "id": int(ng["id"]),
                    "errors": net_errors
                })
        if err_msgs:
            task.result = result
            orm().add(task)
            orm().commit()
            full_err_msg = "\n".join(err_msgs)
            raise errors.NetworkCheckError(full_err_msg)