Exemplo n.º 1
0
def _remove_propagation_from_route_table_item(context, route_table,
                                              gateway_id):
    vgws = route_table['propagating_gateways']
    vgws.remove(gateway_id)
    if not vgws:
        del route_table['propagating_gateways']
    db_api.update_item(context, route_table)
Exemplo n.º 2
0
def delete_route(context, route_table_id, destination_cidr_block):
    route_table = ec2utils.get_db_item(context, route_table_id)
    for route_index, route in enumerate(route_table['routes']):
        if route['destination_cidr_block'] != destination_cidr_block:
            continue
        if route.get('gateway_id', 0) is None:
            msg = _('cannot remove local route %(destination_cidr_block)s '
                    'in route table %(route_table_id)s')
            msg = msg % {'route_table_id': route_table_id,
                         'destination_cidr_block': destination_cidr_block}
            raise exception.InvalidParameterValue(msg)
        break
    else:
        raise exception.InvalidRouteNotFound(
            route_table_id=route_table_id,
            destination_cidr_block=destination_cidr_block)
    update_target = _get_route_target(route)
    if update_target == VPN_TARGET:
        vpn_gateway = db_api.get_item_by_id(context, route['gateway_id'])
        if (not vpn_gateway or
                vpn_gateway['vpc_id'] != route_table['vpc_id']):
            update_target = None
    rollback_route_table_state = copy.deepcopy(route_table)
    del route_table['routes'][route_index]
    with common.OnCrashCleaner() as cleaner:
        db_api.update_item(context, route_table)
        cleaner.addCleanup(db_api.update_item, context,
                           rollback_route_table_state)

        if update_target:
            _update_routes_in_associated_subnets(
                context, cleaner, route_table, update_target=update_target)

    return True
Exemplo n.º 3
0
 def auto_update_db(self, image, os_image):
     if not image:
         kind = _get_os_image_kind(os_image)
         if self.context.project_id == os_image.owner:
             if os_image.properties.get('ec2_id') in self.pending_images:
                 # NOTE(ft): the image is being creating, Glance had created
                 # image, but creating thread doesn't yet update db item
                 image = self.pending_images[os_image.properties['ec2_id']]
                 image['os_id'] = os_image.id
                 image['is_public'] = os_image.is_public
                 db_api.update_item(self.context, image)
             else:
                 image = ec2utils.get_db_item_by_os_id(
                     self.context, kind, os_image.id, self.items_dict,
                     os_image=os_image)
         else:
             image_id = ec2utils.os_id_to_ec2_id(
                 self.context, kind, os_image.id,
                 items_by_os_id=self.items_dict, ids_by_os_id=self.ids_dict)
             image = {'id': image_id,
                      'os_id': os_image.id}
     elif (self.context.project_id == os_image.owner and
             image.get('is_public') != os_image.is_public):
         image['is_public'] = os_image.is_public
         if image['id'] in self.local_images_os_ids:
             db_api.update_item(self.context, image)
         else:
             # TODO(ft): currently update_item can not update id mapping,
             # because its project_id is None. Instead of upgrade db_api,
             # we use add_item. But its execution leads to a needless
             # DB call. This should be reworked in the future.
             kind = ec2utils.get_ec2_id_kind(image['id'])
             db_api.add_item(self.context, kind, image)
     return image
Exemplo n.º 4
0
    def handle_unpaired_item(self, item):
        if item['os_id']:
            return super(ImageDescriber, self).handle_unpaired_item(item)

        if 'is_public' not in item:
            return None

        # NOTE(ft): process creating images, ignoring ids mapping
        # NOTE(ft): the image is being creating, Glance had created
        # image, but creating thread doesn't yet update db item
        os_image = self.ec2_created_os_images.get(item['id'])
        if os_image:
            item['os_id'] = os_image.id
            item['is_public'] = os_image.is_public
            db_api.update_item(self.context, item)
            image = self.format(item, os_image)
        else:
            # NOTE(ft): Glance image is not yet created, but DB item
            # exists. So that we adds EC2 image to output results
            # with all data we have.
            # TODO(ft): check if euca2ools can process such result
            image = {'imageId': item['id'],
                     'imageOwnerId': self.context.project_id,
                     'imageType': IMAGE_TYPES[
                            ec2utils.get_ec2_id_kind(item['id'])],
                     'isPublic': item['is_public']}
            if 'description' in item:
                image['description'] = item['description']
            image['imageState'] = item.get('state', 'pending')
        return image
Exemplo n.º 5
0
def _attach_network_interface_item(context, network_interface, instance_id,
                                   device_index, attach_time=None,
                                   delete_on_termination=False):
    if not attach_time:
        attach_time = timeutils.isotime(None, True)
    network_interface.update({
        'instance_id': instance_id,
        'device_index': device_index,
        'attach_time': attach_time,
        'delete_on_termination': delete_on_termination})
    db_api.update_item(context, network_interface)
Exemplo n.º 6
0
 def test_update_item(self):
     item = db_api.add_item(self.context, 'fake', {'key': 'val1',
                                                   'key1': 'val'})
     item['key'] = 'val2'
     item.pop('key1')
     item['key2'] = 'val'
     item_id = item['id']
     db_api.update_item(self.context, item)
     item = db_api.get_item_by_id(self.context, item_id)
     self.assertThat(item, matchers.DictMatches({'id': item_id,
                                                 'os_id': None,
                                                 'vpc_id': None,
                                                 'key': 'val2',
                                                 'key2': 'val'}))
Exemplo n.º 7
0
def _stop_gateway_vpn_connections(context, neutron, cleaner, vpn_gateway):
    def undo_vpn_connection(context, vpn_connection, connections_ids):
        vpn_connection['os_ipsec_site_connections'] = connections_ids
        db_api.update_item(context, vpn_connection)

    for vpn_connection in db_api.get_items(context, 'vpn'):
        if vpn_connection['vpn_gateway_id'] == vpn_gateway['id']:
            _stop_vpn_connection(neutron, vpn_connection)

            connection_ids = vpn_connection['os_ipsec_site_connections']
            vpn_connection['os_ipsec_site_connections'] = {}
            db_api.update_item(context, vpn_connection)
            cleaner.addCleanup(undo_vpn_connection, context, vpn_connection,
                               connection_ids)
Exemplo n.º 8
0
 def test_update_item_os_id(self):
     item = db_api.add_item(self.context, 'fake', {})
     item['os_id'] = 'fake_os_id'
     db_api.update_item(self.context, item)
     item = db_api.get_item_by_id(self.context, item['id'])
     self.assertThat({'os_id': 'fake_os_id'},
                     matchers.IsSubDictOf(item))
     item['os_id'] = 'other_fake_os_id'
     self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
                       db_api.update_item,
                       self.context, item)
     item['os_id'] = None
     self.assertRaises(exception.EC2DBInvalidOsIdUpdate,
                       db_api.update_item,
                       self.context, item)
Exemplo n.º 9
0
    def delayed_create(context, image, name, os_instance):
        try:
            os_instance.stop()

            # wait instance for really stopped
            start_time = time.time()
            while os_instance.status != 'SHUTOFF':
                time.sleep(1)
                os_instance.get()
                # NOTE(yamahata): timeout and error. 1 hour for now for safety.
                #                 Is it too short/long?
                #                 Or is there any better way?
                timeout = 1 * 60 * 60
                if time.time() > start_time + timeout:
                    err = (_("Couldn't stop instance within %d sec") % timeout)
                    raise exception.EC2Exception(message=err)

            # NOTE(ft): create an image with ec2_id metadata to let other code
            # link os and db objects in race conditions
            os_image_id = os_instance.create_image(
                name, metadata={'ec2_id': image['id']})
            image['os_id'] = os_image_id
            db_api.update_item(context, image)
        except Exception:
            LOG.exception(_LE('Failed to complete image %s creation'),
                          image.id)
            try:
                image['state'] = 'failed'
                db_api.update_item(context, image)
            except Exception:
                LOG.warning(_LW("Couldn't set 'failed' state for db image %s"),
                            image.id, exc_info=True)

        try:
            os_instance.start()
        except Exception:
            LOG.warning(_LW('Failed to start instance %(i_id)s after '
                            'completed creation of image %(image_id)s'),
                        {'i_id': instance['id'],
                         'image_id': image['id']},
                        exc_info=True)
Exemplo n.º 10
0
def create_vpc(context, cidr_block, instance_tenancy='default'):
    neutron = clients.neutron(context)
    with common.OnCrashCleaner() as cleaner:
        os_router_body = {'router': {}}
        try:
            os_router = neutron.create_router(os_router_body)['router']
        except neutron_exception.OverQuotaClient:
            raise exception.VpcLimitExceeded()
        cleaner.addCleanup(neutron.delete_router, os_router['id'])
        vpc = db_api.add_item(context, 'vpc',
                              {'os_id': os_router['id'],
                               'cidr_block': cidr_block})
        cleaner.addCleanup(db_api.delete_item, context, vpc['id'])
        route_table = route_table_api._create_route_table(context, vpc)
        cleaner.addCleanup(route_table_api._delete_route_table,
                           context, route_table['id'])
        vpc['route_table_id'] = route_table['id']
        db_api.update_item(context, vpc)
        neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}})
        security_group_api._create_default_security_group(context, vpc)
    return {'vpc': _format_vpc(vpc)}
Exemplo n.º 11
0
def _create_vpc(context, cidr_block, is_default=False):
    neutron = clients.neutron(context)
    with common.OnCrashCleaner() as cleaner:
        os_router_body = {'router': {}}
        try:
            os_router = neutron.create_router(os_router_body)['router']
        except neutron_exception.OverQuotaClient:
            raise exception.VpcLimitExceeded()
        cleaner.addCleanup(neutron.delete_router, os_router['id'])
        vpc = db_api.add_item(context, 'vpc',
                              {'os_id': os_router['id'],
                               'cidr_block': cidr_block,
                               'is_default': is_default})
        cleaner.addCleanup(db_api.delete_item, context, vpc['id'])
        route_table = route_table_api._create_route_table(context, vpc)
        cleaner.addCleanup(route_table_api._delete_route_table,
                           context, route_table['id'])
        vpc['route_table_id'] = route_table['id']
        db_api.update_item(context, vpc)
        neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}})
        sg_id = security_group_api._create_default_security_group(context, vpc)
        cleaner.addCleanup(security_group_api.delete_security_group, context,
                           group_id=sg_id, delete_default=True)
        if is_default:
            igw_id = internet_gateway_api.create_internet_gateway(
                context)['internetGateway']['internetGatewayId']
            cleaner.addCleanup(internet_gateway_api.delete_internet_gateway,
                               context, igw_id)
            internet_gateway_api.attach_internet_gateway(context, igw_id,
                                                         vpc['id'])
            cleaner.addCleanup(internet_gateway_api.detach_internet_gateway,
                               context, igw_id, vpc['id'])
            subnet = subnet_api.create_subnet(
                context, vpc['id'],
                DEFAULT_SUBNET_CIDR_BLOCK)['subnet']
            cleaner.addCleanup(subnet_api.delete_subnet, context,
                               subnet['subnetId'])
            route_table_api.create_route(context, route_table['id'],
                                         '0.0.0.0/0', gateway_id=igw_id)
    return vpc
Exemplo n.º 12
0
def modify_network_interface_attribute(context, network_interface_id,
                                       description=None,
                                       source_dest_check=None,
                                       security_group_id=None,
                                       attachment=None):
    params_count = (
        int(description is not None) +
        int(source_dest_check is not None) +
        int(security_group_id is not None) +
        int(attachment is not None))
    if params_count != 1:
        raise exception.InvalidParameterCombination(
            'Multiple attributes specified')
    network_interface = ec2utils.get_db_item(context, network_interface_id)
    if description is not None:
        network_interface['description'] = description
        db_api.update_item(context, network_interface)
    neutron = clients.neutron(context)
    if security_group_id is not None:
        os_groups = [sg['os_id']
                     for sg in ec2utils.get_db_items(context, 'sg',
                                                     security_group_id)]
        neutron.update_port(network_interface['os_id'],
                            {'port': {'security_groups': os_groups}})
    if source_dest_check is not None:
        allowed = [] if source_dest_check else [{'ip_address': '0.0.0.0/0'}]
        neutron.update_port(network_interface['os_id'],
                            {'port': {'allowed_address_pairs': allowed}})
        network_interface['source_dest_check'] = source_dest_check
        db_api.update_item(context, network_interface)
    if attachment:
        attachment_id = attachment.get('attachment_id')
        delete_on_termination = attachment.get('delete_on_termination')
        if attachment_id is None or delete_on_termination is None:
            raise exception.MissingParameter(
                _('The request must contain the parameter attachment '
                  'deleteOnTermination'))
        attachment_id_own = ec2utils.change_ec2_id_kind(
                network_interface['id'], 'eni-attach')
        if ('instance_id' not in network_interface
                or attachment_id_own != attachment_id):
            raise exception.InvalidAttachmentIDNotFound(id=attachment_id)
        network_interface['delete_on_termination'] = delete_on_termination
        db_api.update_item(context, network_interface)
    return True
Exemplo n.º 13
0
 def undo_vpn_connection(context, vpn_connection, connections_ids):
     vpn_connection['os_ipsec_site_connections'] = connections_ids
     db_api.update_item(context, vpn_connection)
Exemplo n.º 14
0
def _add_subnet_connection_to_vpn_connection_item(context, vpn_connection,
                                                  subnet_id, os_connection_id):
    vpn_connection['os_ipsec_site_connections'][subnet_id] = os_connection_id
    db_api.update_item(context, vpn_connection)
Exemplo n.º 15
0
def _associate_vpc_item(context, vpc, dhcp_options_id):
    vpc['dhcp_options_id'] = dhcp_options_id
    db_api.update_item(context, vpc)
Exemplo n.º 16
0
def _set_vpnservice_in_subnet_item(context, subnet, os_vpnservice_id):
    subnet['os_vpnservice_id'] = os_vpnservice_id
    db_api.update_item(context, subnet)
Exemplo n.º 17
0
def _attach_vpn_gateway_item(context, vpn_gateway, vpc_id):
    vpn_gateway['vpc_id'] = vpc_id
    db_api.update_item(context, vpn_gateway)
Exemplo n.º 18
0
def _append_propagation_to_route_table_item(context, route_table, gateway_id):
    vgws = route_table.setdefault('propagating_gateways', [])
    vgws.append(gateway_id)
    db_api.update_item(context, route_table)
Exemplo n.º 19
0
def _detach_internet_gateway_item(context, igw):
    igw['vpc_id'] = None
    db_api.update_item(context, igw)
Exemplo n.º 20
0
def _detach_network_interface_item(context, network_interface):
    network_interface.pop('instance_id', None)
    network_interface.pop('device_index', None)
    network_interface.pop('attach_time', None)
    network_interface.pop('delete_on_termination', None)
    db_api.update_item(context, network_interface)
Exemplo n.º 21
0
def _disassociate_address_item(context, address):
    address.pop('network_interface_id')
    address.pop('private_ip_address')
    db_api.update_item(context, address)
Exemplo n.º 22
0
def modify_image_attribute(context,
                           image_id,
                           attribute=None,
                           user_group=None,
                           operation_type=None,
                           description=None,
                           launch_permission=None,
                           product_code=None,
                           user_id=None,
                           value=None):
    os_image = ec2utils.get_os_image(context, image_id)
    if not os_image:
        # TODO(ft): figure out corresponding AWS error
        raise exception.IncorrectState(
            reason='Image is still being created or failed')

    attributes = set()

    # NOTE(andrey-mp): launchPermission structure is converted here
    # to plain parameters: attribute, user_group, operation_type, user_id
    if launch_permission is not None:
        attributes.add('launchPermission')
        user_group = list()
        user_id = list()
        if len(launch_permission) == 0:
            msg = _('No operation specified for launchPermission attribute.')
            raise exception.InvalidParameterCombination(msg)
        if len(launch_permission) > 1:
            msg = _('Only one operation can be specified.')
            raise exception.InvalidParameterCombination(msg)
        operation_type, permissions = launch_permission.popitem()
        for index_key in permissions:
            permission = permissions[index_key]
            if 'group' in permission:
                user_group.append(permission['group'])
            if 'user_id' in permission:
                user_id.append(permission['user_id'])
    if attribute == 'launchPermission':
        attributes.add('launchPermission')

    if description is not None:
        attributes.add('description')
        value = description
    if attribute == 'description':
        attributes.add('description')

    # check attributes
    if len(attributes) == 0:
        if product_code is not None:
            attribute = 'productCodes'
        if attribute in [
                'kernel', 'ramdisk', 'productCodes', 'blockDeviceMapping'
        ]:
            raise exception.InvalidParameter(
                _('Parameter %s is invalid. '
                  'The attribute is not supported.') % attribute)
        raise exception.InvalidParameterCombination('No attributes specified.')
    if len(attributes) > 1:
        raise exception.InvalidParameterCombination(
            _('Fields for multiple attribute types specified: %s') %
            str(attributes))

    if 'launchPermission' in attributes:
        if not user_group:
            msg = _('No operation specified for launchPermission attribute.')
            raise exception.InvalidParameterCombination(msg)
        if len(user_group) != 1 and user_group[0] != 'all':
            msg = _('only group "all" is supported')
            raise exception.InvalidParameterValue(parameter='UserGroup',
                                                  value=user_group,
                                                  reason=msg)
        if operation_type not in ['add', 'remove']:
            msg = _('operation_type must be add or remove')
            raise exception.InvalidParameterValue(parameter='OperationType',
                                                  value='operation_type',
                                                  reason=msg)

        _check_owner(context, os_image)
        os_image.update(is_public=(operation_type == 'add'))
        return True

    if 'description' in attributes:
        if not value:
            raise exception.MissingParameter(
                'The request must contain the parameter description')

        _check_owner(context, os_image)
        image = ec2utils.get_db_item(context, image_id)
        image['description'] = value
        db_api.update_item(context, image)
        return True
Exemplo n.º 23
0
def _associate_address_item(context, address, network_interface_id,
                            private_ip_address):
    address['network_interface_id'] = network_interface_id
    address['private_ip_address'] = private_ip_address
    db_api.update_item(context, address)
Exemplo n.º 24
0
def import_image(context, architecture=None, client_data=None,
                 client_token=None, description=None, disk_container=None,
                 hypervisor=None, license_type=None, platform=None,
                 role_name=None):
    # Check architecture
    validate_enum(architecture, ('i386', 'x86_64'), 'architecture',
                  allow_empty=True)

    # Ignore client_data...?
    if client_data is not None:
        raise exception.Unsupported(reason='Client data is not supported')

    # Ignore client_token...?
    if client_token is not None:
        raise exception.Unsupported(reason='Client token is not supported')

    # Description retrieved below

    # Check disk_container
    disk = disk_container[0]

    url = disk.get('url')
    disk_format = disk.get('format', 'RAW')

    if disk.get('snapshotid') is not None:
        raise exception.Unsupported(reason='Snapshot IDs not supported')

    if url is None or disk.get('userbucket') is not None:
        raise exception.Unsupported(reason='Buckets not implemented. Need URL')

    # disk_container descrption overrides default descrption
    description = disk.get('description') or description

    # hypervisor set below

    # Ignore license_type
    validate_enum(license_type, ('AWS', 'BYOL'), 'license_type', allow_empty=True)

    # Check platform
    validate_enum(platform, ('Linux', 'Windows'), 'platform', allow_empty=True)

    if role_name is not None:
        raise exception.Unsupported(reason='Buckets not implemented. Need URL')

    # Create EC2 image
    ec2_image = { 'is_public': False }
    if description is not None:
        ec2_image['description'] = description
    ec2_image = db_api.add_item(context, 'ami', ec2_image)

    # Create properties for openstack
    properties = {}
    if architecture is not None:
        properties['architecture'] = architecture
    if hypervisor is not None:
        properties['hypervisor_type'] = hypervisor
    if license_type is not None:
        properties['license_type'] = license_type
    if platform is not None:
        properties['os_type'] = platform
    if description is not None:
        properties['description'] = description

    # Set EC2 id for retrieval on the way back
    properties['ec2_id'] = ec2_image['id']

    # Connect to glance
    glance = clients.glance(context)

    # NOTE: container_format is not currently used, so we can always default
    #       to bare. Read more here:
    #       http://docs.openstack.org/developer/glance/formats.html
    os_image = glance.images.create(
            name=ec2_image['id'], copy_from=url, disk_format=disk_format,
            container_format='bare', properties=properties, is_public=False)

    # Update EC2 id
    ec2_image['os_id'] = os_image.id
    db_api.update_item(context, ec2_image)

    return {'imageId': ec2_image['id']}
Exemplo n.º 25
0
def _remove_subnet_connection_from_vpn_connection_item(context, vpn_connection,
                                                       subnet_id):
    del vpn_connection['os_ipsec_site_connections'][subnet_id]
    db_api.update_item(context, vpn_connection)
Exemplo n.º 26
0
def _attach_internet_gateway_item(context, igw, vpc_id):
    igw['vpc_id'] = vpc_id
    db_api.update_item(context, igw)
Exemplo n.º 27
0
def _detach_vpn_gateway_item(context, vpn_gateway):
    vpn_gateway["vpc_id"] = None
    db_api.update_item(context, vpn_gateway)
Exemplo n.º 28
0
def _detach_internet_gateway_item(context, igw):
    igw['vpc_id'] = None
    db_api.update_item(context, igw)
Exemplo n.º 29
0
def _clear_vpnservice_in_subnet_item(context, subnet):
    del subnet["os_vpnservice_id"]
    db_api.update_item(context, subnet)
Exemplo n.º 30
0
def _attach_internet_gateway_item(context, igw, vpc_id):
    igw['vpc_id'] = vpc_id
    db_api.update_item(context, igw)
Exemplo n.º 31
0
def _disassociate_address_item(context, address):
    address.pop('network_interface_id')
    address.pop('private_ip_address')
    db_api.update_item(context, address)
Exemplo n.º 32
0
def modify_image_attribute(context, image_id, attribute=None,
                           user_group=None, operation_type=None,
                           description=None, launch_permission=None,
                           product_code=None, user_id=None, value=None):
    os_image = ec2utils.get_os_image(context, image_id)
    if not os_image:
        # TODO(ft): figure out corresponding AWS error
        raise exception.IncorrectState(
            reason='Image is still being created or failed')

    attributes = set()

    # NOTE(andrey-mp): launchPermission structure is converted here
    # to plain parameters: attribute, user_group, operation_type, user_id
    if launch_permission is not None:
        attributes.add('launchPermission')
        user_group = list()
        user_id = list()
        if len(launch_permission) == 0:
            msg = _('No operation specified for launchPermission attribute.')
            raise exception.InvalidParameterCombination(msg)
        if len(launch_permission) > 1:
            msg = _('Only one operation can be specified.')
            raise exception.InvalidParameterCombination(msg)
        operation_type, permissions = launch_permission.popitem()
        for index_key in permissions:
            permission = permissions[index_key]
            if 'group' in permission:
                user_group.append(permission['group'])
            if 'user_id' in permission:
                user_id.append(permission['user_id'])
    if attribute == 'launchPermission':
        attributes.add('launchPermission')

    if description is not None:
        attributes.add('description')
        value = description
    if attribute == 'description':
        attributes.add('description')

    # check attributes
    if len(attributes) == 0:
        if product_code is not None:
            attribute = 'productCodes'
        if attribute in ['kernel', 'ramdisk', 'productCodes',
                         'blockDeviceMapping']:
            raise exception.InvalidParameter(
                _('Parameter %s is invalid. '
                  'The attribute is not supported.') % attribute)
        raise exception.InvalidParameterCombination('No attributes specified.')
    if len(attributes) > 1:
        raise exception.InvalidParameterCombination(
            _('Fields for multiple attribute types specified: %s')
            % str(attributes))

    if 'launchPermission' in attributes:
        if not user_group:
            msg = _('No operation specified for launchPermission attribute.')
            raise exception.InvalidParameterCombination(msg)
        if len(user_group) != 1 and user_group[0] != 'all':
            msg = _('only group "all" is supported')
            raise exception.InvalidParameterValue(parameter='UserGroup',
                                                  value=user_group,
                                                  reason=msg)
        if operation_type not in ['add', 'remove']:
            msg = _('operation_type must be add or remove')
            raise exception.InvalidParameterValue(parameter='OperationType',
                                                  value='operation_type',
                                                  reason=msg)

        _check_owner(context, os_image)
        os_image.update(is_public=(operation_type == 'add'))
        return True

    if 'description' in attributes:
        if not value:
            raise exception.MissingParameter(
                'The request must contain the parameter description')

        _check_owner(context, os_image)
        image = ec2utils.get_db_item(context, image_id)
        image['description'] = value
        db_api.update_item(context, image)
        return True
Exemplo n.º 33
0
def _add_cidr_to_vpn_connection_item(context, vpn_connection, cidr):
    vpn_connection['cidrs'].append(cidr)
    db_api.update_item(context, vpn_connection)
Exemplo n.º 34
0
def _detach_vpn_gateway_item(context, vpn_gateway):
    vpn_gateway['vpc_id'] = None
    db_api.update_item(context, vpn_gateway)
Exemplo n.º 35
0
def _add_cidr_to_vpn_connection_item(context, vpn_connection, cidr):
    vpn_connection['cidrs'].append(cidr)
    db_api.update_item(context, vpn_connection)
Exemplo n.º 36
0
def _clear_vpnservice_in_subnet_item(context, subnet):
    del subnet['os_vpnservice_id']
    db_api.update_item(context, subnet)
Exemplo n.º 37
0
def _associate_vpc_item(context, vpc, route_table_id):
    vpc['route_table_id'] = route_table_id
    db_api.update_item(context, vpc)
Exemplo n.º 38
0
def _attach_vpn_gateway_item(context, vpn_gateway, vpc_id):
    vpn_gateway["vpc_id"] = vpc_id
    db_api.update_item(context, vpn_gateway)
Exemplo n.º 39
0
def _remove_cidr_from_vpn_connection_item(context, vpn_connection, cidr):
    vpn_connection['cidrs'].remove(cidr)
    db_api.update_item(context, vpn_connection)
Exemplo n.º 40
0
def _set_vpnservice_in_subnet_item(context, subnet, os_vpnservice_id):
    subnet["os_vpnservice_id"] = os_vpnservice_id
    db_api.update_item(context, subnet)
Exemplo n.º 41
0
def _disassociate_subnet_item(context, subnet):
    subnet.pop('route_table_id')
    db_api.update_item(context, subnet)
Exemplo n.º 42
0
def _associate_address_item(context, address, network_interface_id,
                            private_ip_address):
    address['network_interface_id'] = network_interface_id
    address['private_ip_address'] = private_ip_address
    db_api.update_item(context, address)
Exemplo n.º 43
0
def _associate_vpc_item(context, vpc, route_table_id):
    vpc['route_table_id'] = route_table_id
    db_api.update_item(context, vpc)
Exemplo n.º 44
0
def _append_propagation_to_route_table_item(context, route_table, gateway_id):
    vgws = route_table.setdefault('propagating_gateways', [])
    vgws.append(gateway_id)
    db_api.update_item(context, route_table)
Exemplo n.º 45
0
def _add_subnet_connection_to_vpn_connection_item(context, vpn_connection,
                                                  subnet_id, os_connection_id):
    vpn_connection['os_ipsec_site_connections'][subnet_id] = os_connection_id
    db_api.update_item(context, vpn_connection)
Exemplo n.º 46
0
 def undo_vpn_connection(context, vpn_connection, connections_ids):
     vpn_connection['os_ipsec_site_connections'] = connections_ids
     db_api.update_item(context, vpn_connection)
Exemplo n.º 47
0
def _associate_subnet_item(context, subnet, route_table_id):
    subnet['route_table_id'] = route_table_id
    db_api.update_item(context, subnet)
Exemplo n.º 48
0
def _remove_cidr_from_vpn_connection_item(context, vpn_connection, cidr):
    vpn_connection['cidrs'].remove(cidr)
    db_api.update_item(context, vpn_connection)
Exemplo n.º 49
0
def _disassociate_subnet_item(context, subnet):
    subnet.pop('route_table_id')
    db_api.update_item(context, subnet)
Exemplo n.º 50
0
def _remove_subnet_connection_from_vpn_connection_item(context, vpn_connection,
                                                       subnet_id):
    del vpn_connection['os_ipsec_site_connections'][subnet_id]
    db_api.update_item(context, vpn_connection)
Exemplo n.º 51
0
def _set_route(context, route_table_id, destination_cidr_block,
               gateway_id, instance_id, network_interface_id,
               vpc_peering_connection_id, do_replace):
    route_table = ec2utils.get_db_item(context, route_table_id)
    vpc = db_api.get_item_by_id(context, route_table['vpc_id'])
    vpc_ipnet = netaddr.IPNetwork(vpc['cidr_block'])
    route_ipnet = netaddr.IPNetwork(destination_cidr_block)
    if route_ipnet in vpc_ipnet:
        msg = _('Cannot create a more specific route for '
                '%(destination_cidr_block)s than local route '
                '%(vpc_cidr_block)s in route table %(rtb_id)s')
        msg = msg % {'rtb_id': route_table_id,
                     'destination_cidr_block': destination_cidr_block,
                     'vpc_cidr_block': vpc['cidr_block']}
        raise exception.InvalidParameterValue(msg)

    obj_param_count = len([p for p in (gateway_id, network_interface_id,
                                       instance_id, vpc_peering_connection_id)
                           if p is not None])
    if obj_param_count != 1:
        msg = _('The request must contain exactly one of gatewayId, '
                'networkInterfaceId, vpcPeeringConnectionId or instanceId')
        if obj_param_count == 0:
            raise exception.MissingParameter(msg)
        else:
            raise exception.InvalidParameterCombination(msg)

    rollabck_route_table_state = copy.deepcopy(route_table)
    if do_replace:
        route_index, old_route = next(
            ((i, r) for i, r in enumerate(route_table['routes'])
             if r['destination_cidr_block'] == destination_cidr_block),
            (None, None))
        if route_index is None:
            msg = _("There is no route defined for "
                    "'%(destination_cidr_block)s' in the route table. "
                    "Use CreateRoute instead.")
            msg = msg % {'destination_cidr_block': destination_cidr_block}
            raise exception.InvalidParameterValue(msg)
        else:
            del route_table['routes'][route_index]

    if gateway_id:
        gateway = ec2utils.get_db_item(context, gateway_id)
        if gateway.get('vpc_id') != route_table['vpc_id']:
            if ec2utils.get_ec2_id_kind(gateway_id) == 'vgw':
                raise exception.InvalidGatewayIDNotFound(id=gateway['id'])
            else:  # igw
                raise exception.InvalidParameterValue(
                    _('Route table %(rtb_id)s and network gateway %(igw_id)s '
                      'belong to different networks') %
                    {'rtb_id': route_table_id,
                     'igw_id': gateway_id})
        route = {'gateway_id': gateway['id']}
    elif network_interface_id:
        network_interface = ec2utils.get_db_item(context, network_interface_id)
        if network_interface['vpc_id'] != route_table['vpc_id']:
            msg = _('Route table %(rtb_id)s and interface %(eni_id)s '
                    'belong to different networks')
            msg = msg % {'rtb_id': route_table_id,
                         'eni_id': network_interface_id}
            raise exception.InvalidParameterValue(msg)
        route = {'network_interface_id': network_interface['id']}
    elif instance_id:
        # TODO(ft): implement search in DB layer
        network_interfaces = [eni for eni in db_api.get_items(context, 'eni')
                              if eni.get('instance_id') == instance_id]
        if len(network_interfaces) == 0:
            msg = _("Invalid value '%(i_id)s' for instance ID. "
                    "Instance is not in a VPC.")
            msg = msg % {'i_id': instance_id}
            raise exception.InvalidParameterValue(msg)
        elif len(network_interfaces) > 1:
            raise exception.InvalidInstanceId(instance_id=instance_id)
        network_interface = network_interfaces[0]
        if network_interface['vpc_id'] != route_table['vpc_id']:
            msg = _('Route table %(rtb_id)s and interface %(eni_id)s '
                    'belong to different networks')
            msg = msg % {'rtb_id': route_table_id,
                         'eni_id': network_interface['id']}
            raise exception.InvalidParameterValue(msg)
        route = {'network_interface_id': network_interface['id']}
    else:
        raise exception.InvalidRequest('Parameter VpcPeeringConnectionId is '
                                       'not supported by this implementation')
    route['destination_cidr_block'] = destination_cidr_block
    update_target = _get_route_target(route)

    if do_replace:
        idempotent_call = False
        old_target = _get_route_target(old_route)
        if old_target != update_target:
            update_target = None
    else:
        old_route = next((r for r in route_table['routes']
                          if r['destination_cidr_block'] ==
                          destination_cidr_block), None)
        idempotent_call = old_route == route
        if old_route and not idempotent_call:
            raise exception.RouteAlreadyExists(
                destination_cidr_block=destination_cidr_block)

    if not idempotent_call:
        route_table['routes'].append(route)

    with common.OnCrashCleaner() as cleaner:
        db_api.update_item(context, route_table)
        cleaner.addCleanup(db_api.update_item, context,
                           rollabck_route_table_state)
        _update_routes_in_associated_subnets(context, cleaner, route_table,
                                             update_target=update_target)

    return True