Esempio n. 1
0
    def ensure_mesh(self):
        with db.get_object_lock(self, ttl=120, op='Network ensure mesh'):
            # Ensure network was not deleted whilst waiting for the lock.
            if self.is_dead():
                raise DeadNetwork('network=%s' % self)

            removed = []
            added = []

            instances = []
            for iface in db.get_network_interfaces(self.db_entry['uuid']):
                if not iface['instance_uuid'] in instances:
                    instances.append(iface['instance_uuid'])

            node_fqdns = []
            for inst in instances:
                i = db.get_instance(inst)
                if not i:
                    continue
                if not i['node']:
                    continue

                if not i['node'] in node_fqdns:
                    node_fqdns.append(i['node'])

            # NOTE(mikal): why not use DNS here? Well, DNS might be outside
            # the control of the deployer if we're running in a public cloud
            # as an overlay cloud...
            node_ips = [config.NETWORK_NODE_IP]
            for fqdn in node_fqdns:
                ip = db.get_node(fqdn)['ip']
                if ip not in node_ips:
                    node_ips.append(ip)

            discovered = list(self.discover_mesh())
            LOG.withObj(self).withField(
                'discovered', discovered).debug('Discovered mesh elements')

            for node in discovered:
                if node in node_ips:
                    node_ips.remove(node)
                else:
                    self._remove_mesh_element(node)
                    removed.append(node)

            for node in node_ips:
                self._add_mesh_element(node)
                added.append(node)

            if removed:
                db.add_event('network', self.db_entry['uuid'],
                             'remove mesh elements', None, None,
                             ' '.join(removed))
            if added:
                db.add_event('network', self.db_entry['uuid'],
                             'add mesh elements', None, None, ' '.join(added))
Esempio n. 2
0
 def remove_dhcp(self):
     if util.is_network_node():
         subst = self.subst_dict()
         with util.RecordedOperation('remove dhcp', self):
             with db.get_object_lock(self,
                                     ttl=120,
                                     op='Network remove DHCP'):
                 d = dhcp.DHCP(self, subst['vx_veth_inner'])
                 d.remove_dhcpd()
     else:
         db.enqueue('networknode',
                    RemoveDHCPNetworkTask(self.db_entry['uuid']))
         db.add_event('network', self.db_entry['uuid'], 'remove dhcp',
                      'enqueued', None, None)
Esempio n. 3
0
    def update_dhcp(self):
        if not self.db_entry['provide_dhcp']:
            return

        if util.is_network_node():
            subst = self.subst_dict()
            with util.RecordedOperation('update dhcp', self):
                with db.get_object_lock(self,
                                        ttl=120,
                                        op='Network update DHCP'):
                    d = dhcp.DHCP(self, subst['vx_veth_inner'])
                    d.restart_dhcpd()
        else:
            db.enqueue('networknode',
                       UpdateDHCPNetworkTask(self.db_entry['uuid']))
            db.add_event('network', self.db_entry['uuid'], 'update dhcp',
                         'enqueued', None, None)
Esempio n. 4
0
    def delete(self):
        subst = self.subst_dict()
        LOG.withFields(subst).debug('net.delete()')

        # Cleanup local node
        with db.get_object_lock(self, ttl=120, op='Network delete'):
            if util.check_for_interface(subst['vx_bridge']):
                with util.RecordedOperation('delete vxlan bridge', self):
                    util.execute(None, 'ip link delete %(vx_bridge)s' % subst)

            if util.check_for_interface(subst['vx_interface']):
                with util.RecordedOperation('delete vxlan interface', self):
                    util.execute(None,
                                 'ip link delete %(vx_interface)s' % subst)

            # If this is the network node do additional cleanup
            if util.is_network_node():
                if util.check_for_interface(subst['vx_veth_outer']):
                    with util.RecordedOperation('delete router veth', self):
                        util.execute(
                            None, 'ip link delete %(vx_veth_outer)s' % subst)

                if util.check_for_interface(subst['physical_veth_outer']):
                    with util.RecordedOperation('delete physical veth', self):
                        util.execute(
                            None,
                            'ip link delete %(physical_veth_outer)s' % subst)

                if os.path.exists('/var/run/netns/%(netns)s' % subst):
                    with util.RecordedOperation('delete netns', self):
                        util.execute(None, 'ip netns del %(netns)s' % subst)

                if self.db_entry['floating_gateway']:
                    with db.get_lock('ipmanager',
                                     None,
                                     'floating',
                                     ttl=120,
                                     op='Network delete'):
                        ipm = db.get_ipmanager('floating')
                        ipm.release(self.db_entry['floating_gateway'])
                        db.persist_ipmanager('floating', ipm.save())
Esempio n. 5
0
    def deploy_nat(self):
        if not self.db_entry['provide_nat']:
            return

        subst = self.subst_dict()
        if not self.db_entry['floating_gateway']:
            with db.get_lock('ipmanager',
                             None,
                             'floating',
                             ttl=120,
                             op='Network deploy NAT'):
                ipm = db.get_ipmanager('floating')
                self.db_entry[
                    'floating_gateway'] = ipm.get_random_free_address()
                db.persist_ipmanager('floating', ipm.save())
                self.persist_floating_gateway()

        # No lock because no data changing
        ipm = db.get_ipmanager('floating')
        subst['floating_router'] = ipm.get_address_at_index(1)
        subst['floating_gateway'] = self.db_entry['floating_gateway']
        subst['floating_netmask'] = ipm.netmask

        with db.get_object_lock(self, ttl=120, op='Network deploy NAT'):
            # Ensure network was not deleted whilst waiting for the lock.
            if self.is_dead():
                raise DeadNetwork('network=%s' % self)

            with util.RecordedOperation('enable virtual routing', self):
                addresses = util.get_interface_addresses(
                    subst['netns'], subst['physical_veth_inner'])
                if not subst['floating_gateway'] in list(addresses):
                    util.execute(
                        None, '%(in_netns)s ip addr add '
                        '%(floating_gateway)s/%(floating_netmask)s '
                        'dev %(physical_veth_inner)s' % subst)
                    util.execute(
                        None, '%(in_netns)s ip link set '
                        '%(physical_veth_inner)s up' % subst)

                default_routes = util.get_default_routes(subst['netns'])
                if default_routes != [subst['floating_router']]:
                    if default_routes:
                        for default_route in default_routes:
                            util.execute(
                                None, '%s route del default gw %s' %
                                (subst['in_netns'], default_route))

                    util.execute(
                        None, '%(in_netns)s route add default '
                        'gw %(floating_router)s' % subst)

            if not util.nat_rules_for_ipblock(self.network_address):
                with util.RecordedOperation('enable nat', self):
                    util.execute(None,
                                 'echo 1 > /proc/sys/net/ipv4/ip_forward')
                    util.execute(
                        None, '%(in_netns)s iptables -A FORWARD '
                        '-o %(physical_veth_inner)s '
                        '-i %(vx_veth_inner)s -j ACCEPT' % subst)
                    util.execute(
                        None, '%(in_netns)s iptables -A FORWARD '
                        '-i %(physical_veth_inner)s '
                        '-o %(vx_veth_inner)s -j ACCEPT' % subst)
                    util.execute(
                        None, '%(in_netns)s iptables -t nat -A POSTROUTING '
                        '-s %(ipblock)s/%(netmask)s '
                        '-o %(physical_veth_inner)s '
                        '-j MASQUERADE' % subst)
Esempio n. 6
0
    def create(self):
        subst = self.subst_dict()

        with db.get_object_lock(self, ttl=120, op='Network create'):
            # Ensure network was not deleted whilst waiting for the lock.
            if self.is_dead():
                raise DeadNetwork('network=%s' % self)

            if not util.check_for_interface(subst['vx_interface']):
                with util.RecordedOperation('create vxlan interface', self):
                    util.create_interface(
                        subst['vx_interface'], 'vxlan',
                        'id %(vx_id)s dev %(physical_interface)s dstport 0' %
                        subst)
                    util.execute(
                        None, 'sysctl -w net.ipv4.conf.'
                        '%(vx_interface)s.arp_notify=1' % subst)

            if not util.check_for_interface(subst['vx_bridge']):
                with util.RecordedOperation('create vxlan bridge', self):
                    util.create_interface(subst['vx_bridge'], 'bridge', '')
                    util.execute(
                        None, 'ip link set %(vx_interface)s '
                        'master %(vx_bridge)s' % subst)
                    util.execute(None,
                                 'ip link set %(vx_interface)s up' % subst)
                    util.execute(None, 'ip link set %(vx_bridge)s up' % subst)
                    util.execute(
                        None, 'sysctl -w net.ipv4.conf.'
                        '%(vx_bridge)s.arp_notify=1' % subst)
                    util.execute(None, 'brctl setfd %(vx_bridge)s 0' % subst)
                    util.execute(None, 'brctl stp %(vx_bridge)s off' % subst)
                    util.execute(None,
                                 'brctl setageing %(vx_bridge)s 0' % subst)

        if util.is_network_node():
            if not os.path.exists('/var/run/netns/%(netns)s' % subst):
                with util.RecordedOperation('create netns', self):
                    util.execute(None, 'ip netns add %(netns)s' % subst)

            if not util.check_for_interface(subst['vx_veth_outer']):
                with util.RecordedOperation('create router veth', self):
                    util.create_interface(
                        subst['vx_veth_outer'], 'veth',
                        'peer name %(vx_veth_inner)s' % subst)
                    util.execute(
                        None, 'ip link set %(vx_veth_inner)s netns %(netns)s' %
                        subst)
                    util.execute(
                        None,
                        'brctl addif %(vx_bridge)s %(vx_veth_outer)s' % subst)
                    util.execute(None,
                                 'ip link set %(vx_veth_outer)s up' % subst)
                    util.execute(
                        None, '%(in_netns)s ip link set %(vx_veth_inner)s up' %
                        subst)
                    util.execute(
                        None,
                        '%(in_netns)s ip addr add %(router)s/%(netmask)s '
                        'dev %(vx_veth_inner)s' % subst)

            if not util.check_for_interface(subst['physical_veth_outer']):
                with util.RecordedOperation('create physical veth', self):
                    util.create_interface(
                        subst['physical_veth_outer'], 'veth',
                        'peer name %(physical_veth_inner)s' % subst)
                    util.execute(
                        None, 'brctl addif %(physical_bridge)s '
                        '%(physical_veth_outer)s' % subst)
                    util.execute(
                        None, 'ip link set %(physical_veth_outer)s up' % subst)
                    util.execute(
                        None, 'ip link set %(physical_veth_inner)s '
                        'netns %(netns)s' % subst)

            self.deploy_nat()
            self.update_dhcp()
        else:
            db.enqueue('networknode', DeployNetworkTask(self.db_entry['uuid']))
            db.add_event('network', self.db_entry['uuid'], 'deploy',
                         'enqueued', None, None)