Ejemplo n.º 1
0
    def assign_ip_addr(self, org_id, user_id):
        network_hash = self.server.network_hash
        server_id = self.server.id

        response = self.collection.update({
            'network': network_hash,
            'server_id': server_id,
            'user_id': {'$exists': False},
        }, {'$set': {
            'org_id': org_id,
            'user_id': user_id,
        }})
        if response['updatedExisting']:
            return

        network = ipaddress.IPv4Network(self.server.network)
        if self.server.network_start:
            network_start = ipaddress.IPv4Address(self.server.network_start)
        else:
            network_start = None
        if self.server.network_end:
            network_end = ipaddress.IPv4Address(self.server.network_end)
        else:
            network_end = None

        ip_pool = self.get_ip_pool(network, network_start)
        if not ip_pool:
            return

        try:
            doc = self.collection.find({
                'network': network_hash,
                'server_id': server_id,
            }).sort('_id', pymongo.DESCENDING)[0]
            if doc:
                last_addr = doc['_id']
                for remote_ip_addr in ip_pool:
                    if int(remote_ip_addr) == last_addr:
                        break
        except IndexError:
            pass

        for remote_ip_addr in ip_pool:
            if network_end and remote_ip_addr > network_end:
                break

            try:
                self.collection.insert({
                    '_id': int(remote_ip_addr),
                    'network': network_hash,
                    'server_id': server_id,
                    'org_id': org_id,
                    'user_id': user_id,
                    'address': '%s/%s' % (remote_ip_addr, network.prefixlen),
                })
                return True
            except pymongo.errors.DuplicateKeyError:
                pass

        return False
Ejemplo n.º 2
0
    def assign_ip_pool(self, network, network_start,
            network_end, network_hash):
        server_id = self.server.id
        pool_end = False

        network = ipaddress.IPv4Network(network)
        if network_start:
            network_start = ipaddress.IPv4Address(network_start)
        if network_end:
            network_end = ipaddress.IPv4Address(network_end)

        ip_pool = self.get_ip_pool(network, network_start)
        if not ip_pool:
            return

        bulk = self.collection.initialize_unordered_bulk_op()
        bulk_empty = True

        for org in self.server.iter_orgs():
            org_id = org.id

            for user in org.iter_users(include_pool=True):
                try:
                    remote_ip_addr = next(ip_pool)
                    if network_end and remote_ip_addr > network_end:
                        raise StopIteration()
                except StopIteration:
                    pool_end = True
                    break
                doc_id = int(remote_ip_addr)

                spec = {
                    '_id': doc_id,
                }
                doc = {'$set': {
                    '_id': doc_id,
                    'network': network_hash,
                    'server_id': server_id,
                    'org_id': org_id,
                    'user_id': user.id,
                    'address': '%s/%s' % (remote_ip_addr, network.prefixlen),
                }}

                if bulk:
                    bulk.find(spec).upsert().update(doc)
                    bulk_empty = False
                else:
                    self.collection.update(spec, doc, upsert=True)

            if pool_end:
                logger.warning('Failed to assign ip addresses ' +
                    'to server, ip pool empty', 'server',
                    server_id=server_id,
                    org_id=org_id,
                )
                break

        if not bulk_empty:
            bulk.execute()
Ejemplo n.º 3
0
    def get_ip_pool(self, network, network_start):
        ip_pool = network.iterhosts()

        if network_start:
            network_start = ipaddress.IPv4Address(network_start)
            network_break = network_start - 1

            while True:
                try:
                    ip_addr = ip_pool.next()
                except StopIteration:
                    logger.error('Failed to find network start', 'server',
                        server_id=self.server.id,
                    )
                    return

                if ip_addr == network_break:
                    break
        else:
            ip_pool.next()

        return ip_pool
Ejemplo n.º 4
0
    def assign_ip_pool_org(self, org_id):
        org = organization.get_by_id(org_id)
        network_hash = self.server.network_hash
        server_id = self.server.id
        org_id = org.id
        ip_pool_avial = True
        pool_end = False

        network = ipaddress.IPv4Network(self.server.network)
        network_start = self.server.network_start
        network_end = self.server.network_end
        if network_start:
            network_start = ipaddress.IPv4Address(network_start)
        if network_end:
            network_end = ipaddress.IPv4Address(network_end)

        ip_pool = self.get_ip_pool(network, network_start)
        if not ip_pool:
            return

        try:
            doc = self.collection.find({
                'network': network_hash,
                'server_id': server_id,
            }).sort('_id', pymongo.DESCENDING)[0]
            if doc:
                last_addr = doc['_id']

                for remote_ip_addr in ip_pool:
                    if int(remote_ip_addr) == last_addr:
                        break
                    if network_end and remote_ip_addr > network_end:
                        break
        except IndexError:
            pass

        if mongo.has_bulk:
            bulk = self.collection.initialize_unordered_bulk_op()
            bulk_empty = True
        else:
            bulk = None
            bulk_empty = None

        for user in org.iter_users(include_pool=True):
            if ip_pool_avial:
                response = self.collection.update(
                    {
                        'network': network_hash,
                        'server_id': server_id,
                        'user_id': {
                            '$exists': False
                        },
                    }, {'$set': {
                        'org_id': org_id,
                        'user_id': user.id,
                    }})
                if response['updatedExisting']:
                    continue
                ip_pool_avial = False

            try:
                remote_ip_addr = ip_pool.next()
                if network_end and remote_ip_addr > network_end:
                    raise StopIteration()
            except StopIteration:
                pool_end = True
                break
            doc_id = int(remote_ip_addr)

            spec = {
                '_id': doc_id,
            }
            doc = {
                '$set': {
                    '_id': doc_id,
                    'network': network_hash,
                    'server_id': server_id,
                    'org_id': org_id,
                    'user_id': user.id,
                    'address': '%s/%s' % (remote_ip_addr, network.prefixlen),
                }
            }

            if bulk:
                bulk.find(spec).upsert().update(doc)
                bulk_empty = False
            else:
                self.collection.update(spec, doc, upsert=True)

        if bulk and not bulk_empty:
            bulk.execute()

        if pool_end:
            logger.warning(
                'Failed to assign ip addresses ' + 'to org, ip pool empty',
                'server',
                org_id=org_id,
            )
Ejemplo n.º 5
0
def _upgrade_server(server_id, server_path):
    servers_db = get_collection('servers')
    servers_ip_pool_db = get_collection('servers_ip_pool')
    server_conf_path = os.path.join(server_path, 'server.conf')
    dh_param_path = os.path.join(server_path, 'dh_param.pem')
    ip_pool_path = os.path.join(server_path, 'ip_pool')

    spec = {
        '_id': bson.ObjectId(server_id),
    }

    update_doc = {
        'lzo_compression': False,
        'dns_servers': [],
        'protocol': None,
        'links': [],
        'primary_organization': None,
        'instances': [],
        'port': None,
        'network': None,
        'dh_params': None,
        'local_networks': [],
        'primary_user': None,
        'status': ONLINE,
        'debug': False,
        'cipher': 'bf128',
        'bind_address': None,
        'organizations': [],
        'start_timestamp': datetime.datetime.fromtimestamp(0),
        'instances_count': 0,
        'name': None,
        'search_domain': None,
        'replica_count': 1,
        'ca_certificate': None,
        'dh_param_bits': None,
        'mode': None,
        'otp_auth': False,
        'jumbo_frames': False,
        'tls_auth': False,
        'tls_auth_key': None,
        'multi_device': False,
        'hosts': [
            settings.local.host_id,
        ],
    }

    with open(server_conf_path, 'r') as conf_file:
        for line in conf_file.readlines():
            line = line.strip()
            name, value = line.split('=', 1)
            if name in (
                        'primary_user',
                        'primary_organization',
                    ):
                update_doc[name] = bson.ObjectId(value)
            if name in (
                        'name',
                        'protocol',
                        'network',
                        'public_address',
                    ):
                update_doc[name] = value
            elif name in (
                        'port',
                        'dh_param_bits',
                    ):
                update_doc[name] = int(value) if value else None
            elif name in (
                        'lzo_compression',
                        'otp_auth',
                        'debug',
                    ):
                update_doc[name] = True if value == 'true' else False
            elif name in (
                        'organizations',
                        'dns_servers',
                        'debug',
                    ):
                update_doc[name] = value.split(',') if value else []
            elif name == 'mode':
                if value == 'all_traffic':
                    update_doc[name] = ALL_TRAFFIC
                elif value == 'local_traffic':
                    update_doc[name] = LOCAL_TRAFFIC
                elif value == 'vpn_traffic':
                    update_doc[name] = VPN_TRAFFIC

    if os.path.exists(dh_param_path):
        with open(dh_param_path, 'r') as dh_param_file:
            update_doc['dh_params'] = dh_param_file.read().strip()

    if os.path.exists(ip_pool_path):
        with open(ip_pool_path, 'r') as ip_pool_file:
            ip_pool_data = json.loads(ip_pool_file.read())

            network = ip_pool_data['network']
            network_prefixlen = network.split('/')[1]

            for key, value in ip_pool_data.iteritems():
                if key == 'network':
                    continue
                org_id, user_id = key.split('-')
                address, _ = value.split('-')
                address_int = int(ipaddress.IPv4Address(address))

                servers_ip_pool_db.update({
                    '_id': address_int,
                }, {
                    '_id': address_int,
                    'server_id': server_id,
                    'user_id': user_id,
                    'org_id': org_id,
                    'network': network,
                    'address': address + '/' + network_prefixlen,
                }, upsert=True)

    servers_db.update(spec, update_doc, upsert=True)