コード例 #1
0
    def ensure_mesh(self):
        with util.RecordedOperation('ensure mesh', self) as _:
            instances = []
            for iface in db.get_network_interfaces(self.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['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.parsed.get('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.debug('%s: Discovered mesh elements %s' % (self, discovered))
            for node in discovered:
                if node in node_ips:
                    node_ips.remove(node)
                else:
                    self._remove_mesh_element(node)

            for node in node_ips:
                self._add_mesh_element(node)
コード例 #2
0
    def delete(self, network_uuid=None, network_from_db=None):
        db.add_event('network', network_uuid, 'api', 'delete', None, None)
        if network_uuid == 'floating':
            return error(403, 'you cannot delete the floating network')

        # We only delete unused networks
        if len(list(db.get_network_interfaces(network_uuid))) > 0:
            return error(403, 'you cannot delete an in use network')

        # Check if network has already been deleted
        if network_from_db['state'] == 'deleted':
            return error(404, 'network not found')

        with db.get_lock('sf/network/%s' % network_uuid, ttl=900) as _:
            n = net.from_db(network_uuid)
            n.remove_dhcp()
            n.delete()

            if n.floating_gateway:
                with db.get_lock('sf/ipmanager/floating', ttl=120) as _:
                    ipm = db.get_ipmanager('floating')
                    ipm.release(n.floating_gateway)
                    db.persist_ipmanager('floating', ipm.save())

            db.update_network_state(network_uuid, 'deleted')
コード例 #3
0
ファイル: dhcp.py プロジェクト: jackadamson/shakenfist
    def _make_hosts(self):
        if not os.path.exists(self.subst['config_dir']):
            os.makedirs(self.subst['config_dir'])

        t = self._read_template('dhcphosts.tmpl')

        instances = []
        for ni in list(db.get_network_interfaces(self.network_uuid)):
            instance = db.get_instance(ni['instance_uuid'])
            if not instance:
                continue

            instances.append({
                'uuid':
                ni['instance_uuid'],
                'macaddr':
                ni['macaddr'],
                'ipv4':
                ni['ipv4'],
                'name':
                instance.get('name', 'instance').replace(',', '')
            })
        self.subst['instances'] = instances
        c = t.render(self.subst)

        with open(os.path.join(self.subst['config_dir'], 'hosts'), 'w') as f:
            f.write(c)
コード例 #4
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))
コード例 #5
0
ファイル: app.py プロジェクト: jackadamson/shakenfist
    def delete(self, network_uuid=None, network_from_db=None):
        if network_uuid == 'floating':
            return error(403, 'you cannot delete the floating network')

        # We only delete unused networks
        if len(list(db.get_network_interfaces(network_uuid))) > 0:
            return error(403, 'you cannot delete an in use network')

        # Check if network has already been deleted
        if network_from_db['state'] in 'deleted':
            return error(404, 'network not found')

        _delete_network(network_from_db)
コード例 #6
0
    def ensure_mesh(self):
        with db.get_lock('network', None, self.uuid, ttl=120):
            removed = []
            added = []

            instances = []
            for iface in db.get_network_interfaces(self.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.parsed.get('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())
            logutil.debug([self], 'Discovered mesh elements %s' % discovered)
            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.uuid, 'remove mesh elements',
                             None, None, ' '.join(removed))
            if added:
                db.add_event('network', self.uuid, 'add mesh elements', None,
                             None, ' '.join(added))
コード例 #7
0
ファイル: app.py プロジェクト: jackadamson/shakenfist
    def delete(self, confirm=False, namespace=None):
        """Delete all networks in the namespace."""

        if confirm is not True:
            return error(400, 'parameter confirm is not set true')

        if get_jwt_identity() == 'system':
            if not isinstance(namespace, str):
                # A client using a system key must specify the namespace. This
                # ensures that deleting all networks in the cluster (by
                # specifying namespace='system') is a deliberate act.
                return error(400,
                             'system user must specify parameter namespace')

        else:
            if namespace and namespace != get_jwt_identity():
                return error(401, 'you cannot delete other namespaces')
            namespace = get_jwt_identity()

        networks_del = []
        networks_unable = []
        for n in list(db.get_networks(all=all, namespace=namespace)):
            if n['uuid'] == 'floating':
                continue

            if len(list(db.get_network_interfaces(n['uuid']))) > 0:
                logutil.info([n],
                             'Network in use, cannot be deleted by delete-all')
                networks_unable.append(n['uuid'])
                continue

            if n['state'] == 'deleted':
                continue

            _delete_network(n)
            networks_del.append(n['uuid'])

        if networks_unable:
            return error(403, {
                'deleted': networks_del,
                'unable': networks_unable
            })

        return networks_del
コード例 #8
0
    def delete(self, network_uuid=None, network_from_db=None):
        db.add_event('network', network_uuid, 'API DELETE', None, None, None)
        if network_uuid == 'floating':
            return error(403, 'you cannot delete the floating network')

        # We only delete unused networks
        if len(list(db.get_network_interfaces(network_uuid))) > 0:
            return error(403, 'you cannot delete an in use network')

        n = net.from_db(network_uuid)
        n.remove_dhcp()
        n.delete()

        if n.floating_gateway:
            floating_network = net.from_db('floating')
            floating_network.ipmanager.release(n.floating_gateway)
            floating_network.persist_ipmanager()

        db.delete_network(network_uuid)
コード例 #9
0
ファイル: app.py プロジェクト: jackadamson/shakenfist
 def get(self, network_uuid=None, network_from_db=None):
     return list(db.get_network_interfaces(network_uuid))
コード例 #10
0
    def _maintain_networks(self):
        LOG.info('Maintaining networks')

        # Discover what networks are present
        _, _, vxid_to_mac = util.discover_interfaces()

        # Determine what networks we should be on
        host_networks = []
        seen_vxids = []

        if not util.is_network_node():
            # For normal nodes, just the ones we have instances for
            for inst in list(db.get_instances(only_node=config.parsed.get('NODE_NAME'))):
                for iface in db.get_instance_interfaces(inst['uuid']):
                    if not iface['network_uuid'] in host_networks:
                        host_networks.append(iface['network_uuid'])
        else:
            # For network nodes, its all networks
            for n in db.get_networks():
                host_networks.append(n['uuid'])

                # Network nodes also look for interfaces for absent instances
                # and delete them
                for ni in db.get_network_interfaces(n['uuid']):
                    inst = db.get_instance(ni['instance_uuid'])
                    if (not inst
                            or inst.get('state', 'unknown') in ['deleted', 'error', 'unknown']):
                        db.hard_delete_network_interface(ni['uuid'])
                        LOG.withInstance(
                            ni['instance_uuid']).withNetworkInterface(
                            ni['uuid']).info('Hard deleted stray network interface')

        # Ensure we are on every network we have a host for
        for network in host_networks:
            try:
                n = net.from_db(network)
                if not n:
                    continue

                if n.db_entry['state_updated'] - time.time() < 60:
                    # Network state changed in the last minute, punt for now
                    continue

                if not n.is_okay():
                    LOG.withObj(n).info('Recreating not okay network')
                    n.create()

                n.ensure_mesh()
                seen_vxids.append(n.vxlan_id)

            except exceptions.LockException as e:
                LOG.warning(
                    'Failed to acquire lock while maintaining networks: %s' % e)

        # Determine if there are any extra vxids
        extra_vxids = set(vxid_to_mac.keys()) - set(seen_vxids)

        # Delete "deleted" SF networks and log unknown vxlans
        if extra_vxids:
            LOG.withField('vxids', extra_vxids).warning(
                'Extra vxlans present!')

            # Determine the network uuids for those vxids
            # vxid_to_uuid = {}
            # for n in db.get_networks():
            #     vxid_to_uuid[n['vxid']] = n['uuid']

            # for extra in extra_vxids:
            #     if extra in vxid_to_uuid:
            #         with db.get_lock('network', None, vxid_to_uuid[extra],
            #                          ttl=120, op='Network reap VXLAN'):
            #             n = net.from_db(vxid_to_uuid[extra])
            #             n.delete()
            #             LOG.info('Extra vxlan %s (network %s) removed.'
            #                      % (extra, vxid_to_uuid[extra]))
            #     else:
            #         LOG.error('Extra vxlan %s does not map to any network.'
            #                   % extra)

        # And record vxids in the database
        db.persist_node_vxid_mapping(
            config.parsed.get('NODE_NAME'), vxid_to_mac)