def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['patron.context'] authorize(context) address = body['addFloatingIp']['address'] 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 '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)
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': [{'address': '10.0.0.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}, {'address': '2001::1', 'version': 6, 'mac_address': 'aa:aa:aa:aa:aa:aa'}], 'floating_ips': [{'address': '172.16.0.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}, {'address': '172.16.2.1', 'version': 4, 'mac_address': 'aa:aa:aa:aa:aa:aa'}]}, ...} """ nw_info = compute_utils.get_nw_info_for_instance(instance) return get_networks_for_instance_from_nw_info(nw_info)
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
def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['patron.context'] authorize(context) address = body['addFloatingIp']['address'] 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 '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)
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())
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 = objects.SecurityGroupList.get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules = objects.SecurityGroupRuleList.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
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 = objects.SecurityGroupList.get_by_instance( ctxt, instance) # then, security group chains and rules for security_group in security_groups: rules = objects.SecurityGroupRuleList.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