Esempio n. 1
0
    def _test_init_instance_reverts_crashed_migrations(self, old_vm_state=None):
        power_on = True if (not old_vm_state or old_vm_state == vm_states.ACTIVE) else False
        sys_meta = {"old_vm_state": old_vm_state}
        instance = {
            "uuid": "foo",
            "vm_state": vm_states.ERROR,
            "task_state": task_states.RESIZE_MIGRATING,
            "power_state": power_state.SHUTDOWN,
            "system_metadata": sys_meta,
        }
        fixed = dict(instance, task_state=None)
        self.mox.StubOutWithMock(compute_utils, "get_nw_info_for_instance")
        self.mox.StubOutWithMock(utils, "instance_sys_meta")
        self.mox.StubOutWithMock(self.compute.driver, "plug_vifs")
        self.mox.StubOutWithMock(self.compute.driver, "finish_revert_migration")
        self.mox.StubOutWithMock(self.compute, "_get_instance_volume_block_device_info")
        self.mox.StubOutWithMock(self.compute.driver, "get_info")
        self.mox.StubOutWithMock(self.compute, "_instance_update")

        compute_utils.get_nw_info_for_instance(instance).AndReturn(network_model.NetworkInfo())
        self.compute.driver.plug_vifs(instance, [])
        utils.instance_sys_meta(instance).AndReturn(sys_meta)
        self.compute._get_instance_volume_block_device_info(self.context, instance).AndReturn([])
        self.compute.driver.finish_revert_migration(instance, [], [], power_on)
        self.compute._instance_update(self.context, instance["uuid"], task_state=None).AndReturn(fixed)
        self.compute.driver.get_info(fixed).AndReturn({"state": power_state.SHUTDOWN})

        self.mox.ReplayAll()

        self.compute._init_instance(self.context, instance)
Esempio n. 2
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ['nova.context']
        authorize(context)

        address = body['addFloatingIp']['address']

        instance = common.get_instance(self.compute_api, context, id,
                                       want_objects=True)
        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            msg = _('No nw_info cache associated with instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _('No fixed ips associated to instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_address = None
        if 'fixed_address' in body['addFloatingIp']:
            fixed_address = body['addFloatingIp']['fixed_address']
            for fixed in fixed_ips:
                if fixed['address'] == fixed_address:
                    break
            else:
                msg = _('Specified fixed address not assigned to instance')
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if not fixed_address:
            fixed_address = fixed_ips[0]['address']
            if len(fixed_ips) > 1:
                LOG.warning(_LW('multiple fixed_ips exist, using the first: '
                                '%s'), fixed_address)

        try:
            self.network_api.associate_floating_ip(context, instance,
                                  floating_address=address,
                                  fixed_address=fixed_address)
        except exception.FloatingIpAssociated:
            msg = _('floating ip is already associated')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _('l3driver call to add floating ip failed')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.FloatingIpNotFoundForAddress:
            msg = _('floating ip not found')
            raise webob.exc.HTTPNotFound(explanation=msg)
        except exception.Forbidden as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        except Exception as e:
            msg = _('Unable to associate floating ip %(address)s to '
                    'fixed ip %(fixed_address)s for instance %(id)s. '
                    'Error: %(error)s') % (
                    {'address': address, 'fixed_address': fixed_address,
                     'id': id, 'error': e})
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Esempio n. 3
0
    def _prepare_instance(self, context, instance):
        instance["name"] = instance["display_name"]
        instance["status"] = self._status_map.get(
            instance["vm_state"], instance["vm_state"])

        image_id = instance["image_ref"] 
        if image_id is None or len(image_id) == 0:
            image_id = instance["system_metadata"]["image_base_image_ref"]
        if image_id is None or len(image_id) == 0:
            image_id = instance["system_metadata"]["image_image_id"]
        image = image_api.API().get_item_by_id(context, image_id)
        if image is not None:
            instance["image"] = image['name']

        instance["cached_nwinfo"] = \
            compute_utils.get_nw_info_for_instance(instance)

        attached_disks = db.block_device_mapping_get_all_by_instance(
            nova_context.get_admin_context(), instance['uuid'])
        for disk in attached_disks:
            if disk["volume_id"] is not None:
                disk["volume"] = disk_api.API().get_item_by_id(
                    context, disk["volume_id"])
        instance["attached_disks"] = attached_disks

        return instance
Esempio n. 4
0
    def get_vifs_for_instance(self, context, **kwargs):
        """Return the list of VIF for an instance."""
        instance_id = kwargs['instance_id']
        LOG.debug('get_vifs_for_instance %s' % instance_id)
        instance = objects.Instance.get_by_uuid(
            nova_context.get_admin_context(), instance_id)
        hyper_net_info = compute_utils.get_nw_info_for_instance(instance)

        neutron = neutronapi.get_client(context, admin=True)
        check_host_exist(neutron, instance_id)
        tenant_ids = []
        LOG.debug('hyper_net_info: %s' % hyper_net_info)
        for vif in hyper_net_info:
            tenant_ids.append(vif['network']['meta']['tenant_id'])
            neutron.update_port(vif['id'],
                                {'port': {'binding:host_id': instance_id}})
        # get all the tenant router
        LOG.debug('tenant_ids: %s' % tenant_ids)
        for tenant_id in tenant_ids:
            routers = neutron.list_routers({'tenant_id': tenant_id})['routers']
            LOG.debug('routers: %s' % routers)
            for router in routers:
                neutron.update_router(router['id'],
                                      {'router': {'admin_state_up': 'False'}})
                neutron.update_router(router['id'],
                                      {'router': {'admin_state_up': 'True'}})

        return hyper_net_info
Esempio n. 5
0
 def get_vif_for_provider_ip(self, context, **kwargs):
     """Return the VIF for a VM."""
     provider_ip = kwargs['provider_ip']
     LOG.debug("provider ip = % s" % provider_ip)
     # retrieve the instance id from the provider ip
     # from the nova metadata
     filters = {
         'filter': [{'name': 'tag:provider_ip', 'value': provider_ip}]
     }
     instances = objects.InstanceList.get_by_filters(
         context, filters=filters)
     # should return only one and check it
     if len(instances) == 1:
         instance = instances[0]
         vif_id = instance.metadata['ip_%s' % provider_ip]
         hyper_net_info = compute_utils.get_nw_info_for_instance(instance)
         hyper_vif = None
         for vif in hyper_net_info:
             if vif.get('id') == vif_id:
                 hyper_vif = vif
                 break
         neutron = neutronapi.get_client(context, admin=True)
         check_host_exist(neutron, instance.uuid)
         neutron.update_port(hyper_vif,
                             {'port': {'binding:host_id': instance.uuid}})
         return {'instance_id': instance.uuid, 'hyper_vif': hyper_vif}
     else:
         return None
Esempio n. 6
0
def add_floating_ip(uid, pool_name, context):
    """
    Adds an ip to an VM instance.

    uid -- id of the VM.
    pool_name -- name of the pool
    context -- The os context.
    """
    vm_instance = vm.get_vm(uid, context)

    cached_nwinfo = utils.get_nw_info_for_instance(vm_instance)
    if not cached_nwinfo:
        raise AttributeError('No nw_info cache associated with instance')

    fixed_ips = cached_nwinfo.fixed_ips()
    if not fixed_ips:
        raise AttributeError('No fixed ips associated to instance')

    float_address = NETWORK_API.allocate_floating_ip(context, pool_name)

    try:
        address = fixed_ips[0]['address']
        NETWORK_API.associate_floating_ip(context, vm_instance,
                                          float_address, address)
    except exception.FloatingIpAssociated:
        msg = 'floating ip is already associated'
        raise AttributeError(msg)
    except exception.NoFloatingIpInterface:
        msg = 'l3driver call to add floating ip failed'
        raise AttributeError(msg)
    return float_address
Esempio n. 7
0
 def get_vifs_for_instance(self, context, **kwargs):
     """Return the list of VIF for an instance."""
     instance_id = kwargs['instance_id']
     LOG.debug("get_vifs_for_instance %s" % instance_id)
     instance = objects.Instance.get_by_uuid(
         nova_context.get_admin_context(), instance_id)
     net_info = compute_utils.get_nw_info_for_instance(instance)
     # TODO: retrieve the provider_net_info (IP/MAC)
     return {'net_info': net_info,
             'provider_net_info': [None, None, None]}
Esempio n. 8
0
 def _get_instances_with_network(self, context, network, zone_id):
     affected_instances = []
     network_id = network['id']
     instances = self.get_items(context, zone_id)
     for instance in instances:
         cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
         if cached_nwinfo:
             for network_info in cached_nwinfo:
                 if network_id == network_info['network']['id']:
                     affected_instances.append(instance)
     return affected_instances
Esempio n. 9
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ['nova.context']
        authorize(context)

        try:
            address = body['addFloatingIp']['address']
        except TypeError:
            msg = _("Missing parameter dict")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except KeyError:
            msg = _("Address not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        instance = self.compute_api.get(context, id)

        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            msg = _('No nw_info cache associated with instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _('No fixed ips associated to instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        # TODO(tr3buchet): this will associate the floating IP with the
        # first fixed_ip an instance has. This should be
        # changed to support specifying a particular fixed_ip if
        # multiple exist.
        if len(fixed_ips) > 1:
            msg = _('multiple fixed_ips exist, using the first: %s')
            LOG.warning(msg, fixed_ips[0]['address'])

        try:
            self.network_api.associate_floating_ip(context, instance,
                                  floating_address=address,
                                  fixed_address=fixed_ips[0]['address'])
        except exception.FloatingIpAssociated:
            msg = _('floating ip is already associated')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _('l3driver call to add floating ip failed')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except (exception.FloatingIpNotFoundForAddress,
                exception.NotAuthorized):
            msg = _('floating ip not found')
            raise webob.exc.HTTPNotFound(explanation=msg)
        except Exception:
            msg = _('Error. Unable to associate floating ip')
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
    def _get_existing_networks(self, context, server_id):
        """Returns networks a server is already connected to."""
        instance = self.get_instance(context, server_id)
        nw_info = compute_utils.get_nw_info_for_instance(instance)

        networks = []
        for vif in nw_info:
            networks.append(vif["network"]["id"])

        if not networks:
            return set()
        return set(networks)
Esempio n. 11
0
    def _test_init_instance_reverts_crashed_migrations(self,
                                                       old_vm_state=None):
        power_on = True if (not old_vm_state or
                            old_vm_state == vm_states.ACTIVE) else False
        sys_meta = {
            'old_vm_state': old_vm_state
            }
        instance = {
            'uuid': 'foo',
            'vm_state': vm_states.ERROR,
            'task_state': task_states.RESIZE_MIGRATING,
            'power_state': power_state.SHUTDOWN,
            'system_metadata': sys_meta
            }
        fixed = dict(instance, task_state=None)
        self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
        self.mox.StubOutWithMock(utils, 'instance_sys_meta')
        self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
        self.mox.StubOutWithMock(self.compute.driver,
                                 'finish_revert_migration')
        self.mox.StubOutWithMock(self.compute,
                                 '_get_instance_volume_block_device_info')
        self.mox.StubOutWithMock(self.compute.driver, 'get_info')
        self.mox.StubOutWithMock(self.compute, '_instance_update')

        compute_utils.get_nw_info_for_instance(instance).AndReturn(
            network_model.NetworkInfo())
        self.compute.driver.plug_vifs(instance, [])
        utils.instance_sys_meta(instance).AndReturn(sys_meta)
        self.compute._get_instance_volume_block_device_info(
            self.context, instance).AndReturn([])
        self.compute.driver.finish_revert_migration(instance, [], [], power_on)
        self.compute._instance_update(self.context, instance['uuid'],
                                      task_state=None).AndReturn(fixed)
        self.compute.driver.get_info(fixed).AndReturn(
            {'state': power_state.SHUTDOWN})

        self.mox.ReplayAll()

        self.compute._init_instance(self.context, instance)
Esempio n. 12
0
def get_networks_for_instance(context, instance):
    """Returns a prepared nw_info list for passing into the view builders

    We end up with a data structure like::

        {'public': {'ips': [{'addr': '10.0.0.1', 'version': 4},
                            {'addr': '2001::1', 'version': 6}],
                    'floating_ips': [{'addr': '172.16.0.1', 'version': 4},
                                     {'addr': '172.16.2.1', 'version': 4}]},
         ...}
    """
    nw_info = compute_utils.get_nw_info_for_instance(instance)
    return get_networks_for_instance_from_nw_info(nw_info)
Esempio n. 13
0
    def _gather_port_ids(self, context, instance, 
                                      port_ids=None):
        """Return an instance's complete list of port_ids."""

	ifaces = compute_utils.get_nw_info_for_instance(instance)
        # This code path is only done when refreshing the network_cache
        if port_ids is None:
            port_ids = [iface['id'] for iface in ifaces]
        else:
            # an interface was added/removed from instance.
            # Include existing interfaces so they are not removed from the db.
            port_ids = [iface['id'] for iface in ifaces] + port_ids

        return port_ids
 def _get_network_info(self, context, server_id, entity_maker):
     """Returns a list of VIFs, transformed through entity_maker."""
     instance = self._get_instance(context, server_id)
     nw_info = compute_utils.get_nw_info_for_instance(instance)
     vifs = []
     for vif in nw_info:
         addr = [dict(network_id=vif["network"]["id"],
                      network_label=vif["network"]["label"],
                      address=ip["address"]) for ip in vif.fixed_ips()]
         v = dict(address=vif["address"],
                  id=vif["id"],
                  ip_addresses=addr)
         vifs.append(entity_maker(context, v))
     return {'virtual_interfaces': vifs}
Esempio n. 15
0
    def __init__(self, instance, **kwargs):
        super(InstancePayload, self).__init__(**kwargs)

        # Note(gibi): ugly but needed to avoid cyclic import
        from nova.compute import utils

        network_info = utils.get_nw_info_for_instance(instance)
        ips = IpPayload.from_network_info(network_info)

        flavor = flavor_payload.FlavorPayload(flavor=instance.flavor)

        super(InstancePayload, self).__init__(
            ip_addresses=ips,
            flavor=flavor,
            **kwargs)

        self.populate_schema(instance=instance)
Esempio n. 16
0
File: net.py Progetto: dizz/occi-os
def add_flaoting_ip_to_vm(uid, attributes, context):
    """
    Adds an ip to an VM instance.

    uid -- id of the VM.
    attributes -- the call attributes (dict)
    context -- The os context.
    """
    vm_instance = vm.get_vm(uid, context)

    cached_nwinfo = compute_utils.get_nw_info_for_instance(vm_instance)
    if not cached_nwinfo:
        raise AttributeError('No nw_info cache associated with instance')

    fixed_ips = cached_nwinfo.fixed_ips()
    if not fixed_ips:
        raise AttributeError('No fixed ips associated to instance')

    if 'org.openstack.network.floating.pool' not in attributes:
        pool = None
    else:
        pool = attributes['org.openstack.network.floating.pool']

    float_address = NETWORK_API.allocate_floating_ip(context, pool)

    if len(fixed_ips) > 1:
        LOG.warn('multiple fixed_ips exist, using the first')

    try:
        address = fixed_ips[0]['address']
        NETWORK_API.associate_floating_ip(context, vm_instance,
                                          floating_address=float_address,
                                          fixed_address=address)
    except exception.FloatingIpAssociated:
        msg = 'floating ip is already associated'
        raise AttributeError(msg)
    except exception.NoFloatingIpInterface:
        msg = 'l3driver call to add floating ip failed'
        raise AttributeError(msg)
    except Exception as error:
        msg = 'Error. Unable to associate floating ip' + str(error)
        raise AttributeError(msg)
    return float_address
Esempio n. 17
0
    def _build_network_info_model(self, context, instance, networks=None,
                                  port_ids=None):
        LOG.debug('Enter _build_network_info_model with instance %s and '
                  'networks %s' % (instance['project_id'], networks))

        # Get all the nova networks associated with the neutron network passed
        # in.  If no neutron network was passed in, this will return all nova
        # networks.
        net_infos = []
        if networks is None and port_ids is None:
            # We need to check to see if the cache thinks we're none as well
            network_info = compute_utils.get_nw_info_for_instance(instance)

            # If the network info is an empty list...it may be valid.  However,
            # it is improbable.  We should go query against the master list,
            # which is neutron.
            if network_info is None or len(network_info) == 0:
                net_infos = self._update_instance_nw_cache(instance, context)
        # We didn't get the network infos - this could mean that the cache data
        # on the instance is proper. So let's call neutron's parent API and
        # get network details.
        if net_infos == []:
            net_infos = super(PowerVMAPI,
                              self)._build_network_info_model(context,
                                                              instance,
                                                              networks,
                                                              port_ids)
        LOG.debug('Found net_infos %s' % net_infos)

        # Get the neutron networks related to our instance if the invoker did
        # not pass them in.
        if not networks:
            networks = self._get_available_networks(context,
                                                    instance['project_id'])
            msg = (ras.vif_get_msg
                  ('info', 'NO_NET_FOUND') % {'host': instance['host']})
            ras.function_tracepoint(LOG, __name__, ras.TRACE_INFO, msg)

        # Pare down the nova networks list to only include those that map to
        # the neutron network we're interested in.  This will also add in the
        # vlan id to the nova network object.
        return self._match_network_models(networks, net_infos, context)
Esempio n. 18
0
File: api.py Progetto: nash-x/hws
    def _gather_port_ids_and_networks(self, context, instance, networks=None, port_ids=None):
        """Return an instance's complete list of port_ids and networks."""

        if (networks is None and port_ids is not None) or (port_ids is None and networks is not None):
            message = (
                "This method needs to be called with either "
                "networks=None and port_ids=None or port_ids and "
                " networks as not none."
            )
            raise exception.NovaException(message=message)

        ifaces = compute_utils.get_nw_info_for_instance(instance)
        # This code path is only done when refreshing the network_cache
        if port_ids is None:
            port_ids = [iface["id"] for iface in ifaces]
            net_ids = [iface["network"]["id"] for iface in ifaces]

        if networks is None:
            networks = self._get_available_networks(context, instance["project_id"], net_ids)
        # an interface was added/removed from instance.
        else:
            # Since networks does not contain the existing networks on the
            # instance we use their values from the cache and add it.
            networks = networks + [
                {
                    "id": iface["network"]["id"],
                    "name": iface["network"]["label"],
                    "tenant_id": iface["network"]["meta"]["tenant_id"],
                }
                for iface in ifaces
            ]

            # Include existing interfaces so they are not removed from the db.
            port_ids = [iface["id"] for iface in ifaces] + port_ids

        iface_slot_map = {}
        for iface in ifaces:
            iface_slot_map[iface["id"]] = iface["meta"].get("pci_slotnum", None)

        return networks, port_ids, iface_slot_map
Esempio n. 19
0
 def _vpn_dict(self, context, project_id, instance):
     elevated = context.elevated()
     rv = {"project_id": project_id}
     if not instance:
         rv["state"] = "pending"
         return rv
     rv["instance_id"] = instance["uuid"]
     rv["created_at"] = timeutils.isotime(instance["created_at"])
     nw_info = compute_utils.get_nw_info_for_instance(instance)
     if not nw_info:
         return rv
     vif = nw_info[0]
     ips = [ip for ip in vif.fixed_ips() if ip["version"] == 4]
     if ips:
         rv["internal_ip"] = ips[0]["address"]
     # NOTE(vish): Currently network_api.get does an owner check on
     #             project_id. This is probably no longer necessary
     #             but rather than risk changes in the db layer,
     #             we are working around it here by changing the
     #             project_id in the context. This can be removed
     #             if we remove the project_id check in the db.
     elevated.project_id = project_id
     network = self.network_api.get(elevated, vif["network"]["id"])
     if network:
         vpn_ip = network["vpn_public_address"]
         vpn_port = network["vpn_public_port"]
         rv["public_ip"] = vpn_ip
         rv["public_port"] = vpn_port
         if vpn_ip and vpn_port:
             if utils.vpn_ping(vpn_ip, vpn_port):
                 rv["state"] = "running"
             else:
                 rv["state"] = "down"
         else:
             rv["state"] = "invalid"
     return rv
Esempio n. 20
0
 def _vpn_dict(self, context, project_id, instance):
     elevated = context.elevated()
     rv = {'project_id': project_id}
     if not instance:
         rv['state'] = 'pending'
         return rv
     rv['instance_id'] = instance['uuid']
     rv['created_at'] = timeutils.isotime(instance['created_at'])
     nw_info = compute_utils.get_nw_info_for_instance(instance)
     if not nw_info:
         return rv
     vif = nw_info[0]
     ips = [ip for ip in vif.fixed_ips() if ip['version'] == 4]
     if ips:
         rv['internal_ip'] = ips[0]['address']
     # NOTE(vish): Currently network_api.get does an owner check on
     #             project_id. This is probably no longer necessary
     #             but rather than risk changes in the db layer,
     #             we are working around it here by changing the
     #             project_id in the context. This can be removed
     #             if we remove the project_id check in the db.
     elevated.project_id = project_id
     network = self.network_api.get(elevated, vif['network']['id'])
     if network:
         vpn_ip = network['vpn_public_address']
         vpn_port = network['vpn_public_port']
         rv['public_ip'] = vpn_ip
         rv['public_port'] = vpn_port
         if vpn_ip and vpn_port:
             if utils.vpn_ping(vpn_ip, vpn_port):
                 rv['state'] = 'running'
             else:
                 rv['state'] = 'down'
         else:
             rv['state'] = 'invalid'
     return rv
Esempio n. 21
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ['nova.context']
        authorize(context)

        address = body['addFloatingIp']['address']

        instance = common.get_instance(self.compute_api, context, id,
                                       expected_attrs=['flavor'])
        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            LOG.warning(
                _LW('Info cache is %r during associate') % instance.info_cache,
                instance=instance)
            msg = _('No nw_info cache associated with instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _('No fixed IPs associated to instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_address = None
        if 'fixed_address' in body['addFloatingIp']:
            fixed_address = body['addFloatingIp']['fixed_address']
            for fixed in fixed_ips:
                if fixed['address'] == fixed_address:
                    break
            else:
                msg = _('Specified fixed address not assigned to instance')
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if not fixed_address:
            try:
                fixed_address = next(ip['address'] for ip in fixed_ips
                                     if netaddr.valid_ipv4(ip['address']))
            except StopIteration:
                msg = _('Unable to associate floating IP %(address)s '
                        'to any fixed IPs for instance %(id)s. '
                        'Instance has no fixed IPv4 addresses to '
                        'associate.') % (
                        {'address': address, 'id': id})
                raise webob.exc.HTTPBadRequest(explanation=msg)
            if len(fixed_ips) > 1:
                LOG.warning(_LW('multiple fixed_ips exist, using the first '
                                'IPv4 fixed_ip: %s'), fixed_address)

        try:
            self.network_api.associate_floating_ip(context, instance,
                                  floating_address=address,
                                  fixed_address=fixed_address)
        except exception.FloatingIpAssociated:
            msg = _('floating IP is already associated')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _('l3driver call to add floating IP failed')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceUnknownCell as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())
        except exception.FloatingIpNotFoundForAddress:
            msg = _('floating IP not found')
            raise webob.exc.HTTPNotFound(explanation=msg)
        except exception.Forbidden as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        except Exception as e:
            msg = _('Unable to associate floating IP %(address)s to '
                    'fixed IP %(fixed_address)s for instance %(id)s. '
                    'Error: %(error)s') % (
                    {'address': address, 'fixed_address': fixed_address,
                     'id': id, 'error': e})
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Esempio n. 22
0
 def test_instance_dict_none_info_cache(self):
     inst = fake_instance.fake_db_instance(info_cache=None)
     self.assertIsNone(inst['info_cache'])
     result = compute_utils.get_nw_info_for_instance(inst)
     self.assertEqual(jsonutils.dumps([]), result.json())
Esempio n. 23
0
 def test_instance_object_none_info_cache(self):
     inst = fake_instance.fake_instance_obj('fake-context',
                                            expected_attrs=['info_cache'])
     self.assertIsNone(inst.info_cache)
     result = compute_utils.get_nw_info_for_instance(inst)
     self.assertEqual(jsonutils.dumps([]), result.json())
Esempio n. 24
0
    def instance_rules(self, instance, network_info):
        ctxt = context.get_admin_context()

        ipv4_rules = []
        ipv6_rules = []

        # Initialize with basic rules
        self._do_basic_rules(ipv4_rules, ipv6_rules, network_info)
        # Set up rules to allow traffic to/from DHCP server
        self._do_dhcp_rules(ipv4_rules, network_info)

        #Allow project network traffic
        if CONF.allow_same_net_traffic:
            self._do_project_network_rules(ipv4_rules, ipv6_rules,
                                           network_info)
        # We wrap these in CONF.use_ipv6 because they might cause
        # a DB lookup. The other ones are just list operations, so
        # they're not worth the clutter.
        if CONF.use_ipv6:
            # Allow RA responses
            self._do_ra_rules(ipv6_rules, network_info)

        security_groups = self._virtapi.security_group_get_by_instance(
            ctxt, instance)

        # then, security group chains and rules
        for security_group in security_groups:
            rules = self._virtapi.security_group_rule_get_by_security_group(
                ctxt, security_group)

            for rule in rules:
                LOG.debug(_('Adding security group rule: %r'), rule,
                          instance=instance)

                if not rule['cidr']:
                    version = 4
                else:
                    version = netutils.get_ip_version(rule['cidr'])

                if version == 4:
                    fw_rules = ipv4_rules
                else:
                    fw_rules = ipv6_rules

                protocol = rule['protocol']

                if protocol:
                    protocol = rule['protocol'].lower()

                if version == 6 and protocol == 'icmp':
                    protocol = 'icmpv6'

                args = ['-j ACCEPT']
                if protocol:
                    args += ['-p', protocol]

                if protocol in ['udp', 'tcp']:
                    args += self._build_tcp_udp_rule(rule, version)
                elif protocol == 'icmp':
                    args += self._build_icmp_rule(rule, version)
                if rule['cidr']:
                    LOG.debug('Using cidr %r', rule['cidr'], instance=instance)
                    args += ['-s', rule['cidr']]
                    fw_rules += [' '.join(args)]
                else:
                    if rule['grantee_group']:
                        for instance in rule['grantee_group']['instances']:
                            nw_info = compute_utils.get_nw_info_for_instance(
                                    instance)

                            ips = [ip['address']
                                for ip in nw_info.fixed_ips()
                                    if ip['version'] == version]

                            LOG.debug('ips: %r', ips, instance=instance)
                            for ip in ips:
                                subrule = args + ['-s %s' % ip]
                                fw_rules += [' '.join(subrule)]

                LOG.debug('Using fw_rules: %r', fw_rules, instance=instance)

        ipv4_rules += ['-j $sg-fallback']
        ipv6_rules += ['-j $sg-fallback']

        return ipv4_rules, ipv6_rules
Esempio n. 25
0
   def run(self):
       LOG.error('begin time of migrate is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
       bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
               self.context, self.instance['uuid'])
       is_boot_from_image = False
       volume_dict_for_image_id ={}
       #add system_volume
       system_volume=None
       
       data_volume_info_dict={}
       
       
       block_device_mapping = None
       volume_ids = []
       system_volume_image_id = None
       #step1 get the source instance info
       instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) 
       
       #get the interface-port info
       search_opts = {'device_id': instance['uuid']}
       try:
           data = self.network_api.list_ports(self.context, **search_opts)
       except exception.NotFound as e:
           raise exc.HTTPNotFound(explanation=e.format_message())
       except NotImplementedError:
           msg = _("Network driver does not support this function.")
           raise webob.exc.HTTPNotImplemented(explanation=msg)
       ports = data.get('ports', []) 
       access_ip_v4 = instance.access_ip_v4  
       access_ip_v6 = instance.access_ip_v6
       min_count = 1
       max_count = 1
       
       name=instance.display_name
       key_name = None
       metadata = instance.metadata
       injected_files = []
       security_group=instance.security_groups
       user_data=instance.user_data
       
       flavor_id = instance.system_metadata['instance_type_flavorid']
       
       scheduler_hints = {}
       #check_server_group_quota = \
       #    self.ext_mgr.is_loaded('os-server-group-quotas')
       check_server_group_quota=True
       
       requested_networks = []
       nw_info = compute_utils.get_nw_info_for_instance(instance)
       for vif in nw_info:
           net_uuid = vif['network']['id']
           net_ip = vif['network']['subnets'][0]['ips'][0]['address']
           requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid})
       
       requested_networks = self._get_requested_networks(requested_networks)
       
       for port in ports:
           LOG.debug('begin detach the port %s of instance %s' %(port['id'],instance.uuid))
           self.compute_api.detach_interface(self.context,instance, port_id=port['id'])
           time.sleep(2)
           LOG.debug('end detach the port %s of instance %s' %(port['id'],instance.uuid))
       
       for bdm in bdms:
           if bdm.image_id is not None and bdm.boot_index == 0 and bdm.destination_type =='local':
               is_boot_from_image =True
               system_volume_image_id = bdm.image_id
           if bdm.volume_id is not None:
               if bdm.boot_index == 0:
                   volume = self.volume_api.get(self.context, bdm.volume_id)
                   system_volume = volume
                   volume_image_metadata = volume.get('volume_metadata')
                   system_volume_image_id = volume_image_metadata['image_id'] 
               else:
                   volume_info={'boot_index':bdm.boot_index,'mount_point':bdm.device_name}
                   data_volume_info_dict[bdm.volume_id]=volume_info
       #step2 stop the instance
       LOG.error('begin time of stop instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
       self._stop_instance(instance)
       LOG.error('end time of stop instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
       
       #get the image of target vm
       boot_image_uuid = None       
       if is_boot_from_image:
           if self.migrate_system_volume is False:
               boot_image_uuid = system_volume_image_id
           else:
               tmp_image_name = "%[email protected]%s" % (uuid.uuid1(), self.instance.uuid)
               instance = common.get_instance(self.compute_api, self.context, self.instance.uuid, want_objects=True) 
               image_meta = self.compute_api.snapshot(self.context, instance, name=tmp_image_name, extra_properties=None)
               query_image_status_count=1800
               filters = {'name':tmp_image_name}
               imagelist = self.image_api.get_all(self.context,filters=filters)
               image = imagelist[0]
               while image['status'] != 'active':
                   time.sleep(1)
                   imagelist = self.image_api.get_all(self.context,filters=filters)
                   image = imagelist[0]
                   #image_uuid = image['id']
                   #image = self.image_api.get(self.context,image_uuid )
                   if image['status'] =='error':
                       msg = _("migrate vm failed.")
                       raise exc.HTTPBadRequest(explanation=msg)
                   query_image_status_count = query_image_status_count-1
                   if query_image_status_count == 0 and image['status'] != 'active':
                       msg = _("migrate vm failed.")
                       raise exc.HTTPBadRequest(explanation=msg)
               boot_image_uuid =image['id'] 
       else:
           if self.migrate_system_volume is False:
               boot_image_uuid = system_volume_image_id 
           else :
               response = self.volume_api.upload_to_image(self.context,
                                                       system_volume['id'],
                                                       True,
                                                       system_volume['id'],
                                                       'bare',
                                                       'qcow2')
               image_id_of_volume = response[1]['os-volume_upload_image']['image_id']
               image = self.image_api.get(self.context,image_id_of_volume)
               query_image_status_count=1800
               LOG.info('query the image %s status of the voluem %s' %(image_id_of_volume,system_volume['id']))
               while image['status'] != 'active':
                   time.sleep(2)
                   image = self.image_api.get(self.context,image_id_of_volume)
                   if image['status'] == 'error':
                       msg = _("migrate vm failed.")
                       raise exc.HTTPBadRequest(explanation=msg)
                   query_cascaded_image_status_count = query_image_status_count-1
                   if query_cascaded_image_status_count == 0 and image['status'] != 'active':
                       msg = _("migrate vm failed.")
                       raise exc.HTTPBadRequest(explanation=msg)
               boot_image_uuid = image_id_of_volume
       
       
       _get_inst_type = flavors.get_flavor_by_flavor_id
       inst_type = _get_inst_type(flavor_id, ctxt=self.context,
                                          read_deleted="no") 
       instances=self._create_instance(inst_type,boot_image_uuid, display_name=name, 
                          display_description=name,key_name=key_name,metadata=metadata,
                          access_ip_v4=access_ip_v4,access_ip_v6=access_ip_v6,injected_files=injected_files,
                          admin_password=None, min_count=min_count,max_count=max_count, requested_networks=requested_networks,
                          security_group=security_group,  user_data=user_data,availability_zone=self.availability_zone,
                          config_drive=None, block_device_mapping=block_device_mapping, auto_disk_config=None,
                          scheduler_hints=scheduler_hints, legacy_bdm=True,check_server_group_quota=check_server_group_quota) 
          
       volume_dict_for_image_id = self._upload_data_volume_to_image(data_volume_info_dict)
       source_target_vol_mapping = self._create_target_volume(volume_dict_for_image_id) 
        #update the instance metadata the metadata use for vcloud delete vm
       self.compute_api.update_instance_metadata(self.context,instance,{'quick_delete_once': 'True'},delete=False) 
       #step7 delete the vm
       LOG.error('begin time of delete instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
       self.compute_api.delete(self.context,instance)
       LOG.error('end time of delete instance is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
       
       #mount volume and reboot
       instance_new =None
       if instances is not None and len(instances) == 1:
           instance_new = instances[0]
           query_new_vm_status_count=1200
           while instance_new.vm_state != 'active':
               time.sleep(2)
               instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid,
                                      want_objects=True)
               if instance_new.vm_state == 'error' : 
                   LOG.error("bulid instance failed")
                   msg = _("migrate vm failed.")
                   raise exc.HTTPBadRequest(explanation=msg)
               query_new_vm_status_count =query_new_vm_status_count-1
               if query_new_vm_status_count ==0 and instance_new.vm_state != 'active':
                   msg = _("migrate vm failed.")
                   raise exc.HTTPBadRequest(explanation=msg)  
       self._mount_data_volume(instance_new, source_target_vol_mapping, data_volume_info_dict)
       self.compute_api.reboot(self.context, instance_new, 'SOFT')
 
       #step 9 delete the image
       LOG.debug('begin clear the image and volume')
       self._delete_tmp_image(boot_image_uuid, volume_dict_for_image_id)
       #step 10 delete the volume
       self._delete_volume_after_migrate(data_volume_info_dict) 
       
       
       time.sleep(2)
       instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid,
                                      want_objects=True)
       while instance_new.vm_state != 'active':
           time.sleep(2)
           instance_new = common.get_instance(self.compute_api, self.context, instance_new.uuid,
                                  want_objects=True)
           if instance_new.vm_state == 'error' : 
               LOG.error("bulid instance failed")
               msg = _("migrate vm failed.")
               raise exc.HTTPBadRequest(explanation=msg)
           query_new_vm_status_count =query_new_vm_status_count-1
           if query_new_vm_status_count ==0 and instance_new.vm_state != 'active':
               msg = _("migrate vm failed.")
               raise exc.HTTPBadRequest(explanation=msg) 
       LOG.error('end time of migrate is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
Esempio n. 26
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ["nova.context"]
        authorize(context)

        try:
            address = body["addFloatingIp"]["address"]
        except TypeError:
            msg = _("Missing parameter dict")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except KeyError:
            msg = _("Address not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            msg = _("No nw_info cache associated with instance")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _("No fixed ips associated to instance")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_address = None
        if self.ext_mgr.is_loaded("os-extended-floating-ips"):
            if "fixed_address" in body["addFloatingIp"]:
                fixed_address = body["addFloatingIp"]["fixed_address"]
                for fixed in fixed_ips:
                    if fixed["address"] == fixed_address:
                        break
                else:
                    msg = _("Specified fixed address not assigned to instance")
                    raise webob.exc.HTTPBadRequest(explanation=msg)

        if not fixed_address:
            fixed_address = fixed_ips[0]["address"]
            if len(fixed_ips) > 1:
                LOG.warn(_LW("multiple fixed_ips exist, using the first: " "%s"), fixed_address)

        try:
            self.network_api.associate_floating_ip(
                context, instance, floating_address=address, fixed_address=fixed_address
            )
        except exception.FloatingIpAssociated:
            msg = _("floating ip is already associated")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _("l3driver call to add floating ip failed")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.FloatingIpNotFoundForAddress:
            msg = _("floating ip not found")
            raise webob.exc.HTTPNotFound(explanation=msg)
        except exception.Forbidden as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        except Exception as e:
            msg = _(
                "Unable to associate floating ip %(address)s to "
                "fixed ip %(fixed_address)s for instance %(id)s. "
                "Error: %(error)s"
            ) % ({"address": address, "fixed_address": fixed_address, "id": id, "error": e})
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Esempio n. 27
0
 def run(self):
     
    
     #imageName=str(uuid.uuid4())
     
     #create image
     #image_meta = self.compute_api.snapshot(self.context, self.instance, name=imageId, extra_properties=None)
     
     bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
             self.context, self.instance['uuid'])
     volume_ids = [bdm.volume_id for bdm in bdms if bdm.volume_id]
     
      
     image_uuid = None
     if volume_ids is None or volume_ids == []:
         tmp_image_name = "%[email protected]%s" % (uuid.uuid1(), self.instance.uuid)
         image_meta = self.compute_api.snapshot(self.context, self.instance, name=tmp_image_name, extra_properties=None)
         image_uuid = image_meta['id']
         try:
             filters = {'name':tmp_image_name}
             imagelist = self.image_api.get_all(self.context,filters=filters)
             image = imagelist[0]
             while image['status'] != 'active':
                 time.sleep(1) 
                 imagelist = self.image_api.get_all(self.context,filters=filters)
                 image = imagelist[0]
                 image_uuid = image['id']
                 image = self.image_api.get(self.context,image_uuid )
         except (exception.NotFound, exception.InvalidImageRef):
             explanation = _("Image not found.")
             raise webob.exc.HTTPNotFound(explanation=explanation)
          
     else :
         for volume_id in volume_ids:
             volume = self.volume_api.get(self.context, volume_id)
             #import pdb
             #pdb.set_trace()
             response = self.volume_api.upload_to_image(self.context,
                                                             volume_id,
                                                             True,
                                                             volume_id,
                                                             'bare',
                                                             'qcow2')
             image_uuid = response[1]['os-volume_upload_image']['image_id']
      
         #image_uuid = image_meta['id']
         try:
             image = self.image_api.get(self.context, image_uuid)
             cascading_image_name = image['id']
             filters = {'name':cascading_image_name}
             cascading_image = self.image_api.get_all(self.context,filters=filters)
             cascading_image_id = cascading_image[0]['id']
             cascading_image = self.image_api.get(self.context,cascading_image_id )
             while cascading_image['status'] != 'active':
                 time.sleep(1) 
                 cascading_image = self.image_api.get(self.context,cascading_image_id )
         except (exception.NotFound, exception.InvalidImageRef):
             explanation = _("Image not found.")
             raise webob.exc.HTTPNotFound(explanation=explanation)
     
     access_ip_v4 = self.instance.access_ip_v4
     if access_ip_v4 is not None:
         self._validate_access_ipv4(access_ip_v4)
         
     access_ip_v6 = self.instance.access_ip_v6
     if access_ip_v6 is not None:
         self._validate_access_ipv6(access_ip_v6)
         
     #networks = common.get_networks_for_instance(context, instance)
     min_count = 1
     max_count = 1
     
     name=self.instance.display_name
     key_name = None
     metadata = self.instance.metadata
     injected_files = []
     security_group=self.instance.security_groups
     user_data=self.instance.user_data
     
     flavor_id = self.instance.system_metadata['instance_type_flavorid']
     
     scheduler_hints = {}
     legacy_bdm = True
     #check_server_group_quota = \
     #    self.ext_mgr.is_loaded('os-server-group-quotas')
     check_server_group_quota=True
     
     requested_networks = []
     nw_info = compute_utils.get_nw_info_for_instance(self.instance)
     for vif in nw_info:
         net_uuid = vif['network']['id']
         net_ip = vif['network']['subnets'][0]['ips'][0]['address']
         requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid})
     
     requested_networks = self._get_requested_networks(requested_networks)
     #detach port delete
     self.compute_api.delete(self.context,self.instance)
     
     while True:
         time.sleep(3)
         try:
             _get_inst_type = flavors.get_flavor_by_flavor_id
             inst_type = _get_inst_type(flavor_id, ctxt=self.context,
                                        read_deleted="no")
             (instances, resv_id) = self.compute_api.create(self.context,
                         inst_type,
                         image_uuid,
                         display_name=name,
                         display_description=name,
                         key_name=key_name,
                         metadata=metadata,
                         access_ip_v4=access_ip_v4,
                         access_ip_v6=access_ip_v6,
                         injected_files=injected_files,
                         admin_password=None,
                         min_count=min_count,
                         max_count=max_count,
                         requested_networks=requested_networks,
                         security_group=security_group,
                         user_data=user_data,
                         availability_zone=self.availability_zone,
                         config_drive=None,
                         block_device_mapping=None,
                         auto_disk_config=None,
                         scheduler_hints=scheduler_hints,
                         legacy_bdm=legacy_bdm,
                         check_server_group_quota=check_server_group_quota)
         except (exception.QuotaError,
                 exception.PortLimitExceeded) as error:
             raise exc.HTTPForbidden(
                 explanation=error.format_message(),
                 headers={'Retry-After': 0})
         except exception.InvalidMetadataSize as error:
             raise exc.HTTPRequestEntityTooLarge(
                 explanation=error.format_message())
         except exception.ImageNotFound as error:
             msg = _("Can not find requested image")
             raise exc.HTTPBadRequest(explanation=msg)
         except exception.FlavorNotFound as error:
             msg = _("Invalid flavorRef provided.")
             raise exc.HTTPBadRequest(explanation=msg)
         except exception.KeypairNotFound as error:
             msg = _("Invalid key_name provided.")
             raise exc.HTTPBadRequest(explanation=msg)
         except exception.ConfigDriveInvalidValue:
             msg = _("Invalid config_drive provided.")
             raise exc.HTTPBadRequest(explanation=msg)
         except UnicodeDecodeError as error:
             msg = "UnicodeError: %s" % unicode(error)
             raise exc.HTTPBadRequest(explanation=msg)
         except (exception.ImageNotActive,
                 exception.FlavorDiskTooSmall,
                 exception.FlavorMemoryTooSmall,
                 exception.NetworkNotFound,
                 exception.PortNotFound,
                 exception.FixedIpAlreadyInUse,
                 exception.SecurityGroupNotFound,
                 exception.InstanceUserDataTooLarge,
                 exception.InstanceUserDataMalformed) as error:
             raise exc.HTTPBadRequest(explanation=error.format_message())
         except (exception.ImageNUMATopologyIncomplete,
                 exception.ImageNUMATopologyForbidden,
                 exception.ImageNUMATopologyAsymmetric,
                 exception.ImageNUMATopologyCPUOutOfRange,
                 exception.ImageNUMATopologyCPUDuplicates,
                 exception.ImageNUMATopologyCPUsUnassigned,
                 exception.ImageNUMATopologyMemoryOutOfRange) as error:
             raise exc.HTTPBadRequest(explanation=error.format_message())
         except (exception.PortInUse,
                 exception.NoUniqueMatch) as error:
             continue
             raise exc.HTTPConflict(explanation=error.format_message())
         except exception.Invalid as error:
             raise exc.HTTPBadRequest(explanation=error.format_message())
         break
Esempio n. 28
0
    def instance_rules(self, instance, network_info):
        ctxt = context.get_admin_context()
        if isinstance(instance, dict):
            # NOTE(danms): allow old-world instance objects from
            # unconverted callers; all we need is instance.uuid below
            instance = objects.Instance._from_db_object(
                ctxt, objects.Instance(), instance, [])

        ipv4_rules = []
        ipv6_rules = []

        # Initialize with basic rules
        self._do_basic_rules(ipv4_rules, ipv6_rules, network_info)
        # Set up rules to allow traffic to/from DHCP server
        self._do_dhcp_rules(ipv4_rules, network_info)

        #Allow project network traffic
        if CONF.allow_same_net_traffic:
            self._do_project_network_rules(ipv4_rules, ipv6_rules,
                                           network_info)
        # We wrap these in CONF.use_ipv6 because they might cause
        # a DB lookup. The other ones are just list operations, so
        # they're not worth the clutter.
        if CONF.use_ipv6:
            # Allow RA responses
            self._do_ra_rules(ipv6_rules, network_info)

        security_groups = security_group_obj.SecurityGroupList.get_by_instance(
            ctxt, instance)

        # then, security group chains and rules
        for security_group in security_groups:
            rules_cls = security_group_rule_obj.SecurityGroupRuleList
            rules = rules_cls.get_by_security_group(ctxt, security_group)

            for rule in rules:
                if not rule['cidr']:
                    version = 4
                else:
                    version = netutils.get_ip_version(rule['cidr'])

                if version == 4:
                    fw_rules = ipv4_rules
                else:
                    fw_rules = ipv6_rules

                protocol = rule['protocol']

                if protocol:
                    protocol = rule['protocol'].lower()

                if version == 6 and protocol == 'icmp':
                    protocol = 'icmpv6'

                args = ['-j ACCEPT']
                if protocol:
                    args += ['-p', protocol]

                if protocol in ['udp', 'tcp']:
                    args += self._build_tcp_udp_rule(rule, version)
                elif protocol == 'icmp':
                    args += self._build_icmp_rule(rule, version)
                if rule['cidr']:
                    args += ['-s', str(rule['cidr'])]
                    fw_rules += [' '.join(args)]
                else:
                    if rule['grantee_group']:
                        insts = (
                            objects.InstanceList.get_by_security_group(
                                ctxt, rule['grantee_group']))
                        for instance in insts:
                            if instance['info_cache']['deleted']:
                                LOG.debug('ignoring deleted cache')
                                continue
                            nw_info = compute_utils.get_nw_info_for_instance(
                                    instance)

                            ips = [ip['address']
                                for ip in nw_info.fixed_ips()
                                    if ip['version'] == version]

                            LOG.debug('ips: %r', ips, instance=instance)
                            for ip in ips:
                                subrule = args + ['-s %s' % ip]
                                fw_rules += [' '.join(subrule)]

        ipv4_rules += ['-j $sg-fallback']
        ipv6_rules += ['-j $sg-fallback']
        LOG.debug('Security Groups %s translated to ipv4: %r, ipv6: %r',
            security_groups, ipv4_rules, ipv6_rules, instance=instance)
        return ipv4_rules, ipv6_rules
Esempio n. 29
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ['nova.context']
        authorize(context)

        try:
            address = body['addFloatingIp']['address']
        except TypeError:
            msg = _("Missing parameter dict")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except KeyError:
            msg = _("Address not specified")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        instance = common.get_instance(self.compute_api, context, id)
        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            msg = _('No nw_info cache associated with instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _('No fixed ips associated to instance')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_address = None
        if self.ext_mgr.is_loaded('os-extended-floating-ips'):
            if 'fixed_address' in body['addFloatingIp']:
                fixed_address = body['addFloatingIp']['fixed_address']
                for fixed in fixed_ips:
                    if fixed['address'] == fixed_address:
                        break
                else:
                    msg = _('Specified fixed address not assigned to instance')
                    raise webob.exc.HTTPBadRequest(explanation=msg)

        if not fixed_address:
            fixed_address = fixed_ips[0]['address']
            if len(fixed_ips) > 1:
                msg = _('multiple fixed_ips exist, using the first: %s')
                LOG.warning(msg, fixed_address)

        try:
            self.network_api.associate_floating_ip(context, instance,
                                  floating_address=address,
                                  fixed_address=fixed_address)
        except exception.FloatingIpAssociated:
            msg = _('floating ip is already associated')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _('l3driver call to add floating ip failed')
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.FloatingIpNotFoundForAddress:
            msg = _('floating ip not found')
            raise webob.exc.HTTPNotFound(explanation=msg)
        except exception.Forbidden as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        except Exception:
            msg = _('Error. Unable to associate floating ip')
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
Esempio n. 30
0
    def _add_floating_ip(self, req, id, body):
        """Associate floating_ip to an instance."""
        context = req.environ["nova.context"]
        context.can(fi_policies.BASE_POLICY_NAME)

        address = body["addFloatingIp"]["address"]

        instance = common.get_instance(self.compute_api, context, id, expected_attrs=["flavor"])
        cached_nwinfo = compute_utils.get_nw_info_for_instance(instance)
        if not cached_nwinfo:
            LOG.warning(
                _LW("Info cache is %r during associate with no nw_info cache"), instance.info_cache, instance=instance
            )
            msg = _("No nw_info cache associated with instance")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_ips = cached_nwinfo.fixed_ips()
        if not fixed_ips:
            msg = _("No fixed IPs associated to instance")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        fixed_address = None
        if "fixed_address" in body["addFloatingIp"]:
            fixed_address = body["addFloatingIp"]["fixed_address"]
            for fixed in fixed_ips:
                if fixed["address"] == fixed_address:
                    break
            else:
                msg = _("Specified fixed address not assigned to instance")
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if not fixed_address:
            try:
                fixed_address = next(ip["address"] for ip in fixed_ips if netutils.is_valid_ipv4(ip["address"]))
            except StopIteration:
                msg = _(
                    "Unable to associate floating IP %(address)s "
                    "to any fixed IPs for instance %(id)s. "
                    "Instance has no fixed IPv4 addresses to "
                    "associate."
                ) % ({"address": address, "id": id})
                raise webob.exc.HTTPBadRequest(explanation=msg)
            if len(fixed_ips) > 1:
                LOG.warning(_LW("multiple fixed_ips exist, using the first " "IPv4 fixed_ip: %s"), fixed_address)

        try:
            self.network_api.associate_floating_ip(
                context, instance, floating_address=address, fixed_address=fixed_address
            )
        except exception.FloatingIpAssociated:
            msg = _("floating IP is already associated")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.NoFloatingIpInterface:
            msg = _("l3driver call to add floating IP failed")
            raise webob.exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceUnknownCell as e:
            raise webob.exc.HTTPNotFound(explanation=e.format_message())
        except exception.FloatingIpNotFoundForAddress:
            msg = _("floating IP not found")
            raise webob.exc.HTTPNotFound(explanation=msg)
        except exception.Forbidden as e:
            raise webob.exc.HTTPForbidden(explanation=e.format_message())
        except Exception as e:
            msg = _(
                "Unable to associate floating IP %(address)s to "
                "fixed IP %(fixed_address)s for instance %(id)s. "
                "Error: %(error)s"
            ) % ({"address": address, "fixed_address": fixed_address, "id": id, "error": e})
            LOG.exception(msg)
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)