def test_security_group_get_by_instance(self): fake_instance = {"id": "fake-instance"} self.mox.StubOutWithMock(db, "security_group_get_by_instance") db.security_group_get_by_instance(self.context, fake_instance["id"]).AndReturn("it worked") self.mox.ReplayAll() result = self.conductor.security_group_get_by_instance(self.context, fake_instance) self.assertEqual(result, "it worked")
def test_security_group_get_by_instance(self): fake_instance = {'id': 'fake-instance'} self.mox.StubOutWithMock(db, 'security_group_get_by_instance') db.security_group_get_by_instance( self.context, fake_instance['id']).AndReturn('it worked') self.mox.ReplayAll() result = self.conductor.security_group_get_by_instance(self.context, fake_instance) self.assertEqual(result, 'it worked')
def test_security_group_get_by_instance(self): fake_instance = {'id': 'fake-instance'} self.mox.StubOutWithMock(db, 'security_group_get_by_instance') db.security_group_get_by_instance( self.context, fake_instance['id']).AndReturn('it worked') self.mox.ReplayAll() result = self.conductor.security_group_get_by_instance( self.context, fake_instance) self.assertEqual(result, 'it worked')
def test_get_by_instance(self): inst = instance.Instance() inst.uuid = "fake-inst-uuid" self.mox.StubOutWithMock(db, "security_group_get_by_instance") db.security_group_get_by_instance(self.context, "fake-inst-uuid").AndReturn(fake_secgroups) self.mox.ReplayAll() secgroup_list = security_group.SecurityGroupList.get_by_instance(self.context, inst) for i in range(len(fake_secgroups)): self.assertIsInstance(secgroup_list[i], security_group.SecurityGroup) self.assertEqual(fake_secgroups[i]["id"], secgroup_list[i]["id"])
def test_get_by_instance(self): inst = instance.Instance() inst.uuid = 'fake-inst-uuid' self.mox.StubOutWithMock(db, 'security_group_get_by_instance') db.security_group_get_by_instance( self.context, 'fake-inst-uuid').AndReturn(fake_secgroups) self.mox.ReplayAll() secgroup_list = security_group.SecurityGroupList.get_by_instance( self.context, inst) for i in range(len(fake_secgroups)): self.assertTrue( isinstance(secgroup_list[i], security_group.SecurityGroup)) self.assertEqual(fake_secgroups[i]['id'], secgroup_list[i]['id'])
def test_get_by_instance(self): inst = instance.Instance() inst.uuid = 'fake-inst-uuid' self.mox.StubOutWithMock(db, 'security_group_get_by_instance') db.security_group_get_by_instance(self.context, 'fake-inst-uuid').AndReturn( fake_secgroups) self.mox.ReplayAll() secgroup_list = security_group.SecurityGroupList.get_by_instance( self.context, inst) for i in range(len(fake_secgroups)): self.assertTrue(isinstance(secgroup_list[i], security_group.SecurityGroup)) self.assertEqual(fake_secgroups[i]['id'], secgroup_list[i]['id'])
def __init__(self, instance, address=None): self.instance = instance ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance["host"]) self.availability_zone = ec2utils.get_availability_zone_by_host(services, instance["host"]) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance(ctxt, instance["id"]) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get("user_data", None) is not None: self.userdata_b64 = base64.b64decode(instance["user_data"]) else: self.userdata_b64 = None self.ec2_ids = {} self.ec2_ids["instance-id"] = ec2utils.id_to_ec2_inst_id(instance["id"]) self.ec2_ids["ami-id"] = ec2utils.glance_id_to_ec2_id(ctxt, instance["image_ref"]) for image_type in ["kernel", "ramdisk"]: if self.instance.get("%s_id" % image_type): image_id = self.instance["%s_id" % image_type] ec2_image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, ec2_image_type) self.ec2_ids["%s-id" % image_type] = ec2_id self.address = address
def index(self, req, server_id): """Returns a list of security groups for the given instance.""" context = self._authorize_context(req) self.security_group_api.ensure_default(context) try: instance = self.compute_api.get(context, server_id) groups = db.security_group_get_by_instance(context, instance['id']) except exception.ApiError, e: raise webob.exc.HTTPBadRequest(explanation=e.message)
def prepare_instance_filter(self, instance, network_info=None): """Creates an NWFilter for the given instance. In the process, it makes sure the filters for the provider blocks, security groups, and base filter are all in place. """ if not network_info: network_info = netutils.get_network_info(instance) self.refresh_provider_fw_rules() ctxt = context.get_admin_context() instance_secgroup_filter_name = \ '%s-secgroup' % (self._instance_filter_name(instance)) instance_secgroup_filter_children = [ 'nova-base-ipv4', 'nova-base-ipv6', 'nova-allow-dhcp-server' ] if FLAGS.use_ipv6: networks = [ network for (network, _m) in network_info if network['gateway_v6'] ] if networks: instance_secgroup_filter_children.\ append('nova-allow-ra-server') for security_group in \ db.security_group_get_by_instance(ctxt, instance['id']): self.refresh_security_group_rules(security_group['id']) instance_secgroup_filter_children.append('nova-secgroup-%s' % security_group['id']) self._define_filter( self._filter_container(instance_secgroup_filter_name, instance_secgroup_filter_children)) network_filters = self.\ _create_network_filters(instance, network_info, instance_secgroup_filter_name) for (name, children) in network_filters: self._define_filters(name, children)
def test_create_instance_associates_security_groups(self): """Make sure create associates security groups""" group = self._create_group() ref = self.compute_api.create( self.context, instance_type=instance_types.get_default_instance_type(), image_href=None, security_group=['testgroup']) try: self.assertEqual(len(db.security_group_get_by_instance( self.context, ref[0]['id'])), 1) group = db.security_group_get(self.context, group['id']) self.assert_(len(group.instances) == 1) finally: db.security_group_destroy(self.context, group['id']) db.instance_destroy(self.context, ref[0]['id'])
def index(self, req, server_id): """Returns a list of security groups for the given instance.""" context = self._authorize_context(req) self.security_group_api.ensure_default(context) try: instance = self.compute_api.get(context, server_id) except exception.InstanceNotFound as exp: raise exc.HTTPNotFound(explanation=unicode(exp)) groups = db.security_group_get_by_instance(context, instance["id"]) result = [self._format_security_group(context, group) for group in groups] return {"security_groups": list(sorted(result, key=lambda k: (k["tenant_id"], k["name"])))}
def test_create_instance_associates_security_groups(self): """Make sure create associates security groups""" group = self._create_group() ref = self.compute_api.create( self.context, instance_type=FLAGS.default_instance_type, image_id=None, security_group=['testgroup']) try: self.assertEqual(len(db.security_group_get_by_instance( self.context, ref[0]['id'])), 1) group = db.security_group_get(self.context, group['id']) self.assert_(len(group.instances) == 1) finally: db.security_group_destroy(self.context, group['id']) db.instance_destroy(self.context, ref[0]['id'])
def prepare_instance_filter(self, instance, network_info=None): """Creates an NWFilter for the given instance. In the process, it makes sure the filters for the provider blocks, security groups, and base filter are all in place. """ if not network_info: network_info = netutils.get_network_info(instance) self.refresh_provider_fw_rules() ctxt = context.get_admin_context() instance_secgroup_filter_name = \ '%s-secgroup' % (self._instance_filter_name(instance)) instance_secgroup_filter_children = ['nova-base-ipv4', 'nova-base-ipv6', 'nova-allow-dhcp-server'] if FLAGS.use_ipv6: networks = [network for (network, _m) in network_info if network['gateway_v6']] if networks: instance_secgroup_filter_children.\ append('nova-allow-ra-server') for security_group in \ db.security_group_get_by_instance(ctxt, instance['id']): self.refresh_security_group_rules(security_group['id']) instance_secgroup_filter_children.append('nova-secgroup-%s' % security_group['id']) self._define_filter( self._filter_container(instance_secgroup_filter_name, instance_secgroup_filter_children)) network_filters = self.\ _create_network_filters(instance, network_info, instance_secgroup_filter_name) for (name, children) in network_filters: self._define_filters(name, children)
def index(self, req, server_id): """Returns a list of security groups for the given instance.""" context = self._authorize_context(req) self.security_group_api.ensure_default(context) try: instance = self.compute_api.get(context, server_id) except exception.InstanceNotFound as exp: raise exc.HTTPNotFound(explanation=unicode(exp)) groups = db.security_group_get_by_instance(context, instance['id']) result = [self._format_security_group(context, group) for group in groups] return {'security_groups': list(sorted(result, key=lambda k: (k['tenant_id'], k['name'])))}
def __init__(self, instance, address=None): self.instance = instance ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( services, instance['host']) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance( ctxt, instance['id']) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get('user_data', None) is not None: self.userdata_b64 = base64.b64decode(instance['user_data']) else: self.userdata_b64 = None self.ec2_ids = {} self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_inst_id( instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id( ctxt, instance['image_ref']) for image_type in ['kernel', 'ramdisk']: if self.instance.get('%s_id' % image_type): image_id = self.instance['%s_id' % image_type] ec2_image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, ec2_image_type) self.ec2_ids['%s-id' % image_type] = ec2_id self.address = address
def __init__(self, instance, address=None): self.instance = instance ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( services, instance['host']) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance(ctxt, instance['id']) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get('user_data', None) is not None: self.userdata_b64 = base64.b64decode(instance['user_data']) else: self.userdata_b64 = None self.ec2_ids = {} self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_id(instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(ctxt, instance['image_ref']) for image_type in ['kernel', 'ramdisk']: if self.instance.get('%s_id' % image_type): image_id = self.instance['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) self.ec2_ids['%s-id' % image_type] = ec2_id self.address = address
def create_for_vif(self, tenant_id, instance, network, vif_chains, allow_same_net_traffic): LOG.debug('tenant_id=%r, instance=%r, network=%r, vif_chains=%r', tenant_id, instance['id'], network, vif_chains) bridge_uuid = network[0]['id'] net_cidr = network[0]['cidr'] vif_uuid = network[1]['vif_uuid'] mac = network[1]['mac'] ip = network[1]['ips'][0]['ip'] # # ingress # position = 1 in_chain = vif_chains['in'] out_chain = vif_chains['out'] # mac spoofing protection in_chain.add_rule().type('drop')\ .dl_src(mac)\ .inv_dl_src(True)\ .position(position)\ .create() position += 1 # ip spoofing protection in_chain.add_rule().type('drop')\ .nw_src_address(ip)\ .nw_src_length(32)\ .inv_nw_src(True)\ .dl_type(0x0800)\ .position(position)\ .create() position += 1 # conntrack in_chain.add_rule().type('accept')\ .match_forward_flow(True)\ .position(position)\ .create() position += 1 # # egress # ctxt = context.get_admin_context() if self.virtapi: security_groups = self.virtapi.security_group_get_by_instance( ctxt, instance) else: security_groups = db.security_group_get_by_instance(ctxt, instance['id']) position = 1 # get the port groups to match for the rule port_groups = self.mido_api.get_port_groups({'tenant_id': tenant_id}) if allow_same_net_traffic: LOG.debug('accept cidr=%r', net_cidr) nw_src_address, nw_src_length = net_cidr.split('/') out_chain.add_rule().type('accept')\ .nw_src_address(nw_src_address)\ .nw_src_length(nw_src_length)\ .position(position)\ .create() position += 1 # add rules that correspond to Nova SG for sg in security_groups: LOG.debug('security group=%r', sg['name']) if self.virtapi: rules = self.virtapi.security_group_rule_get_by_security_group( ctxt, sg) else: rules = db.security_group_rule_get_by_security_group( ctxt, sg['id']) LOG.debug('sg_id=%r', sg['id']) LOG.debug('sg_project_id=%r', sg['project_id']) LOG.debug('name=%r', sg['name']) LOG.debug('rules=%r', rules) cname = chain_name(sg['id'], sg['name']) chains = self.mido_api.get_chains({'tenant_id': tenant_id}) jump_chain_id = None for c in chains: if c.get_name() == cname: jump_chain_id = c.get_id() break # sg handler must have missed the event of creating the SG. # Now doing the equivalent as a quick workaround. if not jump_chain_id: def create_sg_resources(tenant_id, sg_id, sg_name): self.chain_manager.create_for_sg(tenant_id, sg_id, sg_name) self.pg_manager.create(tenant_id, sg_id, sg_name) create_sg_resources(tenant_id, sg['id'], sg['name']) chains = self.mido_api.get_chains({'tenant_id': tenant_id}) jump_chain_id = None for c in chains: if c.get_name() == cname: jump_chain_id = c.get_id() break assert jump_chain_id rule = out_chain.add_rule().type('jump')\ .position(position)\ .jump_chain_id(jump_chain_id)\ .jump_chain_name(cname)\ .create() position += 1 # Look for the port group that the vif should belong to for pg in port_groups: if pg.get_name() != cname: port_groups.remove(pg) # add reverse flow matching at the end out_chain.add_rule().type('accept')\ .match_return_flow(True)\ .position(position)\ .create() position += 1 # fall back DROP rule at the end except for ARP out_chain.add_rule().type('drop')\ .dl_type(0x0806)\ .inv_dl_type(True)\ .position(position)\ .create() # # Updating the vport # bridge = self.mido_api.get_bridge(bridge_uuid) bridge_port = self.mido_api.get_port(vif_uuid) LOG.debug('bridge_port=%r found', bridge_port) # set filters bridge_port.inbound_filter_id(in_chain.get_id()) bridge_port.outbound_filter_id(out_chain.get_id()) bridge_port.update() for pg in port_groups: pg.add_port_group_port().port_id(bridge_port.get_id()).create()
def security_group_get_by_instance(self, context, instance_uuid): return db.security_group_get_by_instance(context, instance_uuid)
def notify(self, message): ctxt = context.get_admin_context() event_type = message.get('event_type') if event_type in FLAGS.wiki_eventtype_blacklist: return if event_type not in FLAGS.wiki_eventtype_whitelist: LOG.debug("Ignoring message type %s" % event_type) return payload = message['payload'] instance_name = payload['display_name'] uuid = payload['instance_id'] if FLAGS.wiki_instance_dns_domain: fqdn = "%s.%s" % (instance_name, FLAGS.wiki_instance_dns_domain) else: fqdn = instance_name template_param_dict = {} for field in self.RawTemplateFields: template_param_dict[field] = payload[field] tenant_id = payload['tenant_id'] if (FLAGS.wiki_use_keystone and self._keystone_login(tenant_id, ctxt)): tenant_obj = self.tenant_manager[tenant_id].get(tenant_id) user_obj = self.user_manager[tenant_id].get(payload['user_id']) tenant_name = tenant_obj.name user_name = user_obj.name template_param_dict['tenant'] = tenant_name template_param_dict['username'] = user_name inst = db.instance_get_by_uuid(ctxt, uuid) old_school_id = inst.id ec2_id = 'i-%08x' % old_school_id template_param_dict['cpu_count'] = inst.vcpus template_param_dict['disk_gb_current'] = inst.ephemeral_gb template_param_dict['host'] = inst.host template_param_dict['reservation_id'] = inst.reservation_id template_param_dict['availability_zone'] = inst.availability_zone template_param_dict['original_host'] = inst.launched_on template_param_dict['fqdn'] = fqdn template_param_dict['ec2_id'] = ec2_id template_param_dict['project_name'] = inst.project_id template_param_dict['region'] = FLAGS.wiki_instance_region try: fixed_ips = db.fixed_ip_get_by_instance(ctxt, old_school_id) except exception.FixedIpNotFoundForInstance: fixed_ips = [] ips = [] floating_ips = [] for fixed_ip in fixed_ips: ips.append(fixed_ip.address) for floating_ip in db.floating_ip_get_by_fixed_ip_id( ctxt, fixed_ip.id): floating_ips.append(floating_ip.address) template_param_dict['private_ip'] = ','.join(ips) template_param_dict['public_ip'] = ','.join(floating_ips) sec_groups = db.security_group_get_by_instance(ctxt, old_school_id) grps = [grp.name for grp in sec_groups] template_param_dict['security_group'] = ','.join(grps) fields_string = "" for key in template_param_dict: fields_string += "\n|%s=%s" % (key, template_param_dict[key]) if event_type == 'compute.instance.delete.start': page_string = "\n%s\nThis instance has been deleted.\n%s\n" % ( begin_comment, end_comment) else: page_string = "\n%s\n{{InstanceStatus%s}}\n%s\n" % ( begin_comment, fields_string, end_comment) self._wiki_login() pagename = "%s%s" % (FLAGS.wiki_page_prefix, ec2_id) LOG.debug("wikistatus: Writing instance info" " to page http://%s/wiki/%s" % (FLAGS.wiki_host, pagename)) page = self.site.Pages[pagename] try: pText = page.edit() start_replace_index = pText.find(begin_comment) if start_replace_index == -1: # Just stick it at the end. newText = "%s%s" % (page_string, pText) else: # Replace content between comment tags. end_replace_index = pText.find(end_comment, start_replace_index) if end_replace_index == -1: end_replace_index = start_replace_index + len( begin_comment) else: end_replace_index += len(end_comment) newText = "%s%s%s" % (pText[:start_replace_index], page_string, pText[end_replace_index:]) page.save(newText, "Auto update of instance info.") except (mwclient.errors.InsufficientPermission, mwclient.errors.LoginError): LOG.debug("Failed to update wiki page..." " trying to re-login next time.") self._wiki_logged_in = False
def instance_rules(self, instance, network_info=None): if not network_info: network_info = netutils.get_network_info(instance) ctxt = context.get_admin_context() ipv4_rules = [] ipv6_rules = [] # Always drop invalid packets ipv4_rules += ['-m state --state ' 'INVALID -j DROP'] ipv6_rules += ['-m state --state ' 'INVALID -j DROP'] # Allow established connections ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] # Pass through provider-wide drops ipv4_rules += ['-j $provider'] ipv6_rules += ['-j $provider'] dhcp_servers = [info['gateway'] for (_n, info) in network_info] for dhcp_server in dhcp_servers: ipv4_rules.append('-s %s -p udp --sport 67 --dport 68 ' '-j ACCEPT' % (dhcp_server,)) #Allow project network traffic if FLAGS.allow_project_net_traffic: cidrs = [network['cidr'] for (network, _m) in network_info] for cidr in cidrs: ipv4_rules.append('-s %s -j ACCEPT' % (cidr,)) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses gateways_v6 = [mapping['gateway6'] for (_n, mapping) in network_info] for gateway_v6 in gateways_v6: ipv6_rules.append( '-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)) #Allow project network traffic if FLAGS.allow_project_net_traffic: cidrv6s = [network['cidr_v6'] for (network, _m) in network_info] for cidrv6 in cidrv6s: ipv6_rules.append('-s %s -j ACCEPT' % (cidrv6,)) security_groups = db.security_group_get_by_instance(ctxt, instance['id']) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group(ctxt, security_group['id']) for rule in rules: LOG.debug(_('Adding security group rule: %r'), rule) if not rule.cidr: # Eventually, a mechanism to grant access for security # groups will turn up here. It'll use ipsets. continue version = netutils.get_ip_version(rule.cidr) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule.protocol if version == 6 and rule.protocol == 'icmp': protocol = 'icmpv6' args = ['-p', protocol, '-s', rule.cidr] if rule.protocol in ['udp', 'tcp']: if rule.from_port == rule.to_port: args += ['--dport', '%s' % (rule.from_port,)] else: args += ['-m', 'multiport', '--dports', '%s:%s' % (rule.from_port, rule.to_port)] elif rule.protocol == 'icmp': icmp_type = rule.from_port icmp_code = rule.to_port if icmp_type == -1: icmp_type_arg = None else: icmp_type_arg = '%s' % icmp_type if not icmp_code == -1: icmp_type_arg += '/%s' % icmp_code if icmp_type_arg: if version == 4: args += ['-m', 'icmp', '--icmp-type', icmp_type_arg] elif version == 6: args += ['-m', 'icmp6', '--icmpv6-type', icmp_type_arg] args += ['-j ACCEPT'] fw_rules += [' '.join(args)] ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def get_metadata(self, address): ctxt = context.get_admin_context() search_opts = {'fixed_ip': address, 'deleted': False} try: instance_ref = self.compute_api.get_all(ctxt, search_opts=search_opts) except exception.NotFound: instance_ref = None if not instance_ref: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref[0]['id']) mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host( services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_ec2_id = ec2utils.image_ec2_id(instance_ref['image_ref']) security_groups = db.security_group_get_by_instance( ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': { 'availability-zone': availability_zone }, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups, 'mpi': mpi } } # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': { '_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data'] } } for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): ec2_id = ec2utils.image_ec2_id( instance_ref['%s_id' % image_type], ec2utils.image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] return data
def get_by_instance(cls, context, instance): return _make_secgroup_list(context, cls(), db.security_group_get_by_instance( context, instance.uuid))
def instance_rules(self, instance, network_info): # make sure this is legacy nw_info network_info = self._handle_network_info_model(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 FLAGS.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = db.security_group_get_by_instance( ctxt, instance['id']) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group( ctxt, security_group['id']) 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']: # FIXME(jkoelker) This needs to be ported up into # the compute manager which already # has access to a nw_api handle, # and should be the only one making # making rpc calls. nw_api = network.API() for instance in rule['grantee_group']['instances']: nw_info = nw_api.get_instance_nw_info( ctxt, 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
def notify(self, message): ctxt = context.get_admin_context() event_type = message.get('event_type') if event_type in FLAGS.wiki_eventtype_blacklist: return if event_type not in FLAGS.wiki_eventtype_whitelist: LOG.debug("Ignoring message type %s" % event_type) return payload = message['payload'] instance_name = payload['display_name'] uuid = payload['instance_id'] if FLAGS.wiki_instance_dns_domain: fqdn = "%s.%s" % (instance_name, FLAGS.wiki_instance_dns_domain) else: fqdn = instance_name template_param_dict = {} for field in self.RawTemplateFields: template_param_dict[field] = payload[field] tenant_id = payload['tenant_id'] if (FLAGS.wiki_use_keystone and self._keystone_login(tenant_id, ctxt)): tenant_obj = self.tenant_manager[tenant_id].get(tenant_id) user_obj = self.user_manager[tenant_id].get(payload['user_id']) tenant_name = tenant_obj.name user_name = user_obj.name template_param_dict['tenant'] = tenant_name template_param_dict['username'] = user_name inst = db.instance_get_by_uuid(ctxt, uuid) old_school_id = inst.id ec2_id = 'i-%08x' % old_school_id template_param_dict['cpu_count'] = inst.vcpus template_param_dict['disk_gb_current'] = inst.ephemeral_gb template_param_dict['host'] = inst.host template_param_dict['reservation_id'] = inst.reservation_id template_param_dict['availability_zone'] = inst.availability_zone template_param_dict['original_host'] = inst.launched_on template_param_dict['fqdn'] = fqdn template_param_dict['ec2_id'] = ec2_id template_param_dict['project_name'] = inst.project_id template_param_dict['region'] = FLAGS.wiki_instance_region try: fixed_ips = db.fixed_ip_get_by_instance(ctxt, old_school_id) except exception.FixedIpNotFoundForInstance: fixed_ips = [] ips = [] floating_ips = [] for fixed_ip in fixed_ips: ips.append(fixed_ip.address) for floating_ip in db.floating_ip_get_by_fixed_ip_id(ctxt, fixed_ip.id): floating_ips.append(floating_ip.address) template_param_dict['private_ip'] = ','.join(ips) template_param_dict['public_ip'] = ','.join(floating_ips) sec_groups = db.security_group_get_by_instance(ctxt, old_school_id) grps = [grp.name for grp in sec_groups] template_param_dict['security_group'] = ','.join(grps) fields_string = "" for key in template_param_dict: fields_string += "\n|%s=%s" % (key, template_param_dict[key]) if event_type == 'compute.instance.delete.start': page_string = "\n%s\nThis instance has been deleted.\n%s\n" % (begin_comment, end_comment) else: page_string = "\n%s\n{{InstanceStatus%s}}\n%s\n" % (begin_comment, fields_string, end_comment) self._wiki_login() pagename = "%s%s" % (FLAGS.wiki_page_prefix, ec2_id) LOG.debug("wikistatus: Writing instance info" " to page http://%s/wiki/%s" % (FLAGS.wiki_host, pagename)) page = self.site.Pages[pagename] try: pText = page.edit() start_replace_index = pText.find(begin_comment) if start_replace_index == -1: # Just stick it at the end. newText = "%s%s" % (page_string, pText) else: # Replace content between comment tags. end_replace_index = pText.find(end_comment, start_replace_index) if end_replace_index == -1: end_replace_index = start_replace_index + len(begin_comment) else: end_replace_index += len(end_comment) newText = "%s%s%s" % (pText[:start_replace_index], page_string, pText[end_replace_index:]) page.save(newText, "Auto update of instance info.") except (mwclient.errors.InsufficientPermission, mwclient.errors.LoginError): LOG.debug("Failed to update wiki page..." " trying to re-login next time.") self._wiki_logged_in = False
def get_by_instance(cls, context, instance): groups = db.security_group_get_by_instance(context, instance.uuid) return base.obj_make_list(context, cls(context), objects.SecurityGroup, groups)
def instance_rules(self, instance, network_info=None): if not network_info: network_info = netutils.get_network_info(instance) ctxt = context.get_admin_context() ipv4_rules = [] ipv6_rules = [] # Always drop invalid packets ipv4_rules += ["-m state --state " "INVALID -j DROP"] ipv6_rules += ["-m state --state " "INVALID -j DROP"] # Allow established connections ipv4_rules += ["-m state --state ESTABLISHED,RELATED -j ACCEPT"] ipv6_rules += ["-m state --state ESTABLISHED,RELATED -j ACCEPT"] # Pass through provider-wide drops ipv4_rules += ["-j $provider"] ipv6_rules += ["-j $provider"] dhcp_servers = [info["gateway"] for (_n, info) in network_info] for dhcp_server in dhcp_servers: ipv4_rules.append("-s %s -p udp --sport 67 --dport 68 " "-j ACCEPT" % (dhcp_server,)) # Allow project network traffic if FLAGS.allow_project_net_traffic: cidrs = [network["cidr"] for (network, _m) in network_info] for cidr in cidrs: ipv4_rules.append("-s %s -j ACCEPT" % (cidr,)) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses gateways_v6 = [mapping["gateway6"] for (_n, mapping) in network_info] for gateway_v6 in gateways_v6: ipv6_rules.append("-s %s/128 -p icmpv6 -j ACCEPT" % (gateway_v6,)) # Allow project network traffic if FLAGS.allow_project_net_traffic: cidrv6s = [network["cidr_v6"] for (network, _m) in network_info] for cidrv6 in cidrv6s: ipv6_rules.append("-s %s -j ACCEPT" % (cidrv6,)) security_groups = db.security_group_get_by_instance(ctxt, instance["id"]) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group(ctxt, security_group["id"]) for rule in rules: LOG.debug(_("Adding security group rule: %r"), rule) if not rule.cidr: # Eventually, a mechanism to grant access for security # groups will turn up here. It'll use ipsets. continue version = netutils.get_ip_version(rule.cidr) if version == 4: fw_rules = ipv4_rules else: fw_rules = ipv6_rules protocol = rule.protocol if version == 6 and rule.protocol == "icmp": protocol = "icmpv6" args = ["-p", protocol, "-s", rule.cidr] if rule.protocol in ["udp", "tcp"]: if rule.from_port == rule.to_port: args += ["--dport", "%s" % (rule.from_port,)] else: args += ["-m", "multiport", "--dports", "%s:%s" % (rule.from_port, rule.to_port)] elif rule.protocol == "icmp": icmp_type = rule.from_port icmp_code = rule.to_port if icmp_type == -1: icmp_type_arg = None else: icmp_type_arg = "%s" % icmp_type if not icmp_code == -1: icmp_type_arg += "/%s" % icmp_code if icmp_type_arg: if version == 4: args += ["-m", "icmp", "--icmp-type", icmp_type_arg] elif version == 6: args += ["-m", "icmp6", "--icmpv6-type", icmp_type_arg] args += ["-j ACCEPT"] fw_rules += [" ".join(args)] ipv4_rules += ["-j $sg-fallback"] ipv6_rules += ["-j $sg-fallback"] return ipv4_rules, ipv6_rules
def security_group_get_by_instance(self, context, instance): return db.security_group_get_by_instance(context, instance['id'])
def _fullbuild(conn): LOG.debug('_fullbuild begin') tenants_networks_filters = {} def _extend(tenant_id, network_id, filter_bodys): if tenant_id not in tenants_networks_filters: tenants_networks_filters[tenant_id] = {} if network_id not in tenants_networks_filters[tenant_id]: tenants_networks_filters[tenant_id][network_id] = [] tenants_networks_filters[tenant_id][network_id].extend(filter_bodys) ctxt = context.get_admin_context() hosts = bmdb.bm_node_get_all(ctxt) for t in hosts: if not t.instance_id: continue LOG.debug('to id=%s instance_id=%s', t.id, t.instance_id) ti = db.instance_get(ctxt, t.instance_id) # DHCP from the instance for (in_port, network_uuid, mac, _) \ in _from_bm_node(ti.id, ti.project_id): filter_bodys = [] filter_bodys.extend(_build_allow_dhcp_client(in_port, mac)) filter_bodys.extend(_build_deny_dhcp_server(in_port)) LOG.debug("filter_bodys: %s", filter_bodys) _extend(ti.project_id, network_uuid, filter_bodys) # from external host to the instance LOG.debug('from=* to.id=%s', t.id) for (_, network_uuid, _, t_ips) in _from_bm_node(ti.id, ti.project_id): filter_bodys = [] for t_ip in t_ips: for sg in db.security_group_get_by_instance(ctxt, ti.id): rules = db.security_group_rule_get_by_security_group( ctxt, sg.id) for rule in rules: rule_f = _build_sg_rule_filter( t_ip + "/32", rule, EXTERNAL_SECURITY_GROUP_PRIORITY) filter_bodys.extend(rule_f) rule_f = _build_default_drop_filter(t_ip + "/32") filter_bodys.extend(rule_f) LOG.debug("filter_bodys: %s", filter_bodys) _extend(ti.project_id, network_uuid, filter_bodys) # Just to make lines short... _sg_rules = db.security_group_rule_get_by_security_group _build = _build_full_sg_rule_filter # from other instances to the instance for f in hosts: LOG.debug('from.id=%s to.id=%s', f.id, t.id) if f.id == t.id: continue if not f.instance_id: continue fi = db.instance_get(ctxt, f.instance_id) LOG.debug('from id=%s instance_id=%s', f.id, f.instance_id) for (in_port, network_uuid, mac, f_ips) in _from_bm_node(fi.id, fi.project_id): filter_bodys = [] for (_, _, _, t_ips) in _from_bm_node(ti.id, ti.project_id): for f_ip in f_ips: for t_ip in t_ips: for sg in db.security_group_get_by_instance( ctxt, ti.id): rules = _sg_rules(ctxt, sg.id) for rule in rules: if rule.cidr and not _in_cidr( f_ip, rule.cidr): continue rule_f = _build(in_port, mac, f_ip + "/32", t_ip + "/32", rule) filter_bodys.extend(rule_f) rule_f = _build_full_default_drop_filter( in_port, mac, f_ip + "/32", t_ip + "/32") filter_bodys.extend(rule_f) LOG.debug("filter_bodys: %s", filter_bodys) _extend(fi.project_id, network_uuid, filter_bodys) LOG.debug('begin update filters') for (tenant_id, nf) in tenants_networks_filters.iteritems(): for (network_id, filter_bodys) in nf.iteritems(): old_fids = _list_filters(conn, tenant_id, network_id) LOG.debug("delete filters tenant_id=%s network_id=%s ids=\n%s", tenant_id, network_id, _pp(old_fids)) _delete_filters(conn, tenant_id, network_id, old_fids) LOG.debug("create filters tenant_id=%s network_id=%s bodys=\n%s", tenant_id, network_id, _pp(filter_bodys)) _create_filters(conn, tenant_id, network_id, filter_bodys) LOG.debug('end update filters') LOG.debug('_fullbuild end')
def get_metadata(self, address): if not address: raise exception.FixedIpNotFoundForAddress(address=address) cache_key = 'metadata-%s' % address data = self._cache.get(cache_key) if data: return data ctxt = context.get_admin_context() try: fixed_ip = self.network_api.get_fixed_ip_by_address(ctxt, address) instance_ref = db.instance_get(ctxt, fixed_ip['instance_id']) except exception.NotFound: return None hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host(services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_id = instance_ref['image_ref'] ctxt = context.get_admin_context() image_ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id) security_groups = db.security_group_get_by_instance(ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': {'availability-zone': availability_zone}, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups}} # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': {'_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data']}} for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): image_id = instance_ref['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] self._cache.set(cache_key, data, 15) return data
def instance_rules(self, instance, network_info): # make sure this is legacy nw_info network_info = self._handle_network_info_model(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) # NOTE: (stanzgy) insert intranet firewall rule here # # iptables -I nova-compute-inst-{inst-id} 4 # -m set --match-set {inst-set-name} src -j ACCEPT # # then drop all other packets not been NATed # # iptables -I nova-compute-inst-[inst-id] 5 -d fixed_range # -m conntrack ! --ctstate DNAT -j DROP if FLAGS.intranet_firewall_mode == 'tenant': setname = instance['project_id'][0:31] self._do_intranet_firewall_rules(ipv4_rules, ipv6_rules, setname) #Allow project network traffic if FLAGS.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) # Allow IP encapsulated in IP packets? if FLAGS.allow_ipencap: self._do_ipencap_rules(ipv4_rules, ipv6_rules) security_groups = db.security_group_get_by_instance(ctxt, instance['id']) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group(ctxt, security_group['id']) 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']: # FIXME(jkoelker) This needs to be ported up into # the compute manager which already # has access to a nw_api handle, # and should be the only one making # making rpc calls. import nova.network nw_api = nova.network.API() for instance in rule['grantee_group']['instances']: nw_info = nw_api.get_instance_nw_info(ctxt, 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
def _fullbuild(conn): tenants_networks_filters = {} def _extend(tenant_id, network_id, filter_bodys): if not tenants_networks_filters.has_key(tenant_id): tenants_networks_filters[tenant_id] = {} if not tenants_networks_filters[tenant_id].has_key(network_id): tenants_networks_filters[tenant_id][network_id] = [] tenants_networks_filters[tenant_id][network_id].extend(filter_bodys) ctxt = context.get_admin_context() hosts = db.phy_host_get_all(ctxt) for t in hosts: LOG.debug('to.id=%s', t.id) LOG.debug('to=%s', t.__dict__) if not t.instance_id: continue ti = db.instance_get(ctxt, t.instance_id) LOG.debug('to.instance=%s', ti.__dict__) # DHCP from the instance for (in_port,network_uuid,mac,_) in _from_phy_host(ti.id, ti.project_id): filter_bodys = [] filter_bodys.extend(_build_allow_dhcp_client(in_port, mac)) filter_bodys.extend(_build_deny_dhcp_server(in_port)) _extend(ti.project_id, network_uuid, filter_bodys) # from external host to the instance LOG.debug('from=* to.id=%s', t.id) for (_,network_uuid,_,t_ips) in _from_phy_host(ti.id, ti.project_id): filter_bodys = [] for t_ip in t_ips: for sg in db.security_group_get_by_instance(ctxt, ti.id): rules = db.security_group_rule_get_by_security_group(ctxt, sg.id) for rule in rules: rule_f = _build_security_group_rule_filter(t_ip + "/32", rule, EXTERNAL_SECURITY_GROUP_PRIORITY) filter_bodys.extend(rule_f) rule_f = _build_default_drop_filter(t_ip + "/32") filter_bodys.extend(rule_f) _extend(ti.project_id, network_uuid, filter_bodys) # from other instances to the instance for f in hosts: LOG.debug('from.id=%s to.id=%s', f.id, t.id) if f.id == t.id: continue if not f.instance_id: continue fi = db.instance_get(ctxt, f.instance_id) LOG.debug('from.instance=%s', fi.__dict__) for (in_port,network_uuid,mac,f_ips) in _from_phy_host(fi.id, fi.project_id): filter_bodys = [] for (_,_,_,t_ips) in _from_phy_host(ti.id, ti.project_id): for f_ip in f_ips: for t_ip in t_ips: for sg in db.security_group_get_by_instance(ctxt, ti.id): rules = db.security_group_rule_get_by_security_group(ctxt, sg.id) for rule in rules: if rule.cidr and not _in_cidr(f_ip, rule.cidr): continue rule_f = _build_full_security_group_rule_filter(in_port, mac, f_ip + "/32", t_ip + "/32", rule) filter_bodys.extend(rule_f) rule_f = _build_full_default_drop_filter(in_port, mac, f_ip + "/32", t_ip + "/32") filter_bodys.extend(rule_f) _extend(fi.project_id, network_uuid, filter_bodys) LOG.debug('begin update filters') for (tenant_id, nf) in tenants_networks_filters.iteritems(): for (network_id, filter_bodys) in nf.iteritems(): old_fids = _list_filters(conn, tenant_id, network_id) LOG.debug("delete filters tenant_id=%s network_id=%s ids=\n%s", tenant_id, network_id, _pp(old_fids)) _delete_filters(conn, tenant_id, network_id, old_fids) LOG.debug("create filters tenant_id=%s network_id=%s bodys=\n%s", tenant_id, network_id, _pp(filter_bodys)) _create_filters(conn, tenant_id, network_id, filter_bodys) LOG.debug('end update filters')
def __init__(self, instance, address=None, content=[], extra_md=None): """Creation of this object should basically cover all time consuming collection. Methods after that should not cause time delays due to network operations or lengthy cpu operations. The user should then get a single instance and make multiple method calls on it. """ self.instance = instance self.extra_md = extra_md ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( services, instance['host']) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance(ctxt, instance['id']) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get('user_data', None) is not None: self.userdata_raw = base64.b64decode(instance['user_data']) else: self.userdata_raw = None self.ec2_ids = {} self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_inst_id( instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(ctxt, instance['image_ref']) for image_type in ['kernel', 'ramdisk']: if self.instance.get('%s_id' % image_type): image_id = self.instance['%s_id' % image_type] ec2_image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, ec2_image_type) self.ec2_ids['%s-id' % image_type] = ec2_id self.address = address # expose instance metadata. self.launch_metadata = {} for item in instance.get('metadata', []): self.launch_metadata[item['key']] = item['value'] self.uuid = instance.get('uuid') self.content = {} self.files = [] # get network info, and the rendered network template ctxt = context.get_admin_context() network_info = network.API().get_instance_nw_info(ctxt, instance) self.network_config = None cfg = netutils.get_injected_network_template(network_info) if cfg: key = "%04i" % len(self.content) self.content[key] = cfg self.network_config = {"name": "network_config", 'content_path': "/%s/%s" % (CONTENT_DIR, key)} # 'content' is passed in from the configdrive code in # nova/virt/libvirt/driver.py. Thats how we get the injected files # (personalities) in. AFAIK they're not stored in the db at all, # so are not available later (web service metadata time). for (path, contents) in content: key = "%04i" % len(self.content) self.files.append({'path': path, 'content_path': "/%s/%s" % (CONTENT_DIR, key)}) self.content[key] = contents
def get_metadata(self, address): ctxt = context.get_admin_context() search_opts = {'fixed_ip': address, 'deleted': False} try: instance_ref = self.compute_api.get_all(ctxt, search_opts=search_opts) except exception.NotFound: instance_ref = None if not instance_ref: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref[0]['id']) mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host(services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_ec2_id = ec2utils.image_ec2_id(instance_ref['image_ref']) security_groups = db.security_group_get_by_instance(ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': {'availability-zone': availability_zone}, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups, 'mpi': mpi}} # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': {'_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data']}} for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): ec2_id = ec2utils.image_ec2_id( instance_ref['%s_id' % image_type], ec2utils.image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] return data
def get_metadata(self, address): if not address: raise exception.FixedIpNotFoundForAddress(address=address) cache_key = 'metadata-%s' % address data = self._cache.get(cache_key) if data: return data ctxt = context.get_admin_context() try: fixed_ip = self.network_api.get_fixed_ip_by_address(ctxt, address) instance_ref = db.instance_get(ctxt, fixed_ip['instance_id']) except exception.NotFound: return None hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host( services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_id = instance_ref['image_ref'] ctxt = context.get_admin_context() image_ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id) security_groups = db.security_group_get_by_instance( ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': { 'availability-zone': availability_zone }, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups } } # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': { '_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data'] } } for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): image_id = instance_ref['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] self._cache.set(cache_key, data, 15) return data
def instance_rules(self, instance, network_info): ctxt = context.get_admin_context() ipv4_rules = [] ipv6_rules = [] # Always drop invalid packets ipv4_rules += ['-m state --state ' 'INVALID -j DROP'] ipv6_rules += ['-m state --state ' 'INVALID -j DROP'] # Allow established connections ipv4_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] ipv6_rules += ['-m state --state ESTABLISHED,RELATED -j ACCEPT'] # Pass through provider-wide drops ipv4_rules += ['-j $provider'] ipv6_rules += ['-j $provider'] dhcp_servers = [info['dhcp_server'] for (_n, info) in network_info] for dhcp_server in dhcp_servers: ipv4_rules.append('-s %s -p udp --sport 67 --dport 68 ' '-j ACCEPT' % (dhcp_server, )) #Allow project network traffic if FLAGS.allow_same_net_traffic: cidrs = [network['cidr'] for (network, _m) in network_info] for cidr in cidrs: ipv4_rules.append('-s %s -j ACCEPT' % (cidr, )) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses gateways_v6 = [ mapping['gateway6'] for (_n, mapping) in network_info ] for gateway_v6 in gateways_v6: ipv6_rules.append('-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6, )) #Allow project network traffic if FLAGS.allow_same_net_traffic: cidrv6s = [ network['cidr_v6'] for (network, _m) in network_info ] for cidrv6 in cidrv6s: ipv6_rules.append('-s %s -j ACCEPT' % (cidrv6, )) security_groups = db.security_group_get_by_instance( ctxt, instance['id']) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group( ctxt, security_group['id']) for rule in rules: LOG.debug(_('Adding security group rule: %r'), rule) 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 version == 6 and rule.protocol == 'icmp': protocol = 'icmpv6' args = ['-j ACCEPT'] if protocol: args += ['-p', protocol] if protocol in ['udp', 'tcp']: if rule.from_port == rule.to_port: args += ['--dport', '%s' % (rule.from_port, )] else: args += [ '-m', 'multiport', '--dports', '%s:%s' % (rule.from_port, rule.to_port) ] elif protocol == 'icmp': icmp_type = rule.from_port icmp_code = rule.to_port if icmp_type == -1: icmp_type_arg = None else: icmp_type_arg = '%s' % icmp_type if not icmp_code == -1: icmp_type_arg += '/%s' % icmp_code if icmp_type_arg: if version == 4: args += [ '-m', 'icmp', '--icmp-type', icmp_type_arg ] elif version == 6: args += [ '-m', 'icmp6', '--icmpv6-type', icmp_type_arg ] if rule.cidr: LOG.info('Using cidr %r', rule.cidr) args += ['-s', rule.cidr] fw_rules += [' '.join(args)] else: if rule['grantee_group']: for instance in rule['grantee_group']['instances']: LOG.info('instance: %r', instance) ips = db.instance_get_fixed_addresses( ctxt, instance['id']) LOG.info('ips: %r', ips) for ip in ips: subrule = args + ['-s %s' % ip] fw_rules += [' '.join(subrule)] LOG.info('Using fw_rules: %r', fw_rules) ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def notify(self, ctxt, message): event_type = message.get('event_type') if event_type in FLAGS.wiki_eventtype_blacklist: return if event_type not in FLAGS.wiki_eventtype_whitelist: LOG.debug("Ignoring message type %s" % event_type) return payload = message['payload'] instance = payload['instance_id'] instance_name = payload['display_name'] pagename = "%s%s" % (FLAGS.wiki_page_prefix, instance_name) LOG.debug("wikistatus: Writing instance info" " to page http://%s/wiki/%s" % (self.host, pagename)) if event_type == 'compute.instance.delete.end': page_string = _("This instance has been deleted.") else: template_param_dict = {} for field in self.RawTemplateFields: template_param_dict[field] = payload[field] tenant_id = payload['tenant_id'] if (FLAGS.wiki_use_keystone and self._keystone_login(tenant_id, ctxt)): tenant_obj = self.tenant_manager[tenant_id].get(tenant_id) user_obj = self.user_manager[tenant_id].get(payload['user_id']) tenant_name = tenant_obj.name user_name = user_obj.name template_param_dict['tenant'] = tenant_name template_param_dict['username'] = user_name inst = db.instance_get_by_uuid(ctxt, payload['instance_id']) simple_id = inst.id template_param_dict['cpu_count'] = inst.vcpus template_param_dict['disk_gb_current'] = inst.ephemeral_gb template_param_dict['host'] = inst.host template_param_dict['reservation_id'] = inst.reservation_id template_param_dict['availability_zone'] = inst.availability_zone template_param_dict['original_host'] = inst.launched_on template_param_dict['public_ip'] = inst.access_ip_v4 try: fixed_ips = db.fixed_ip_get_by_instance(ctxt, payload['instance_id']) except exception.FixedIpNotFoundForInstance: fixed_ips = [] ips = [ip.address for ip in fixed_ips] template_param_dict['private_ip'] = ','.join(ips) sec_groups = db.security_group_get_by_instance(ctxt, simple_id) grps = [grp.name for grp in sec_groups] template_param_dict['security_group'] = ','.join(grps) image = self._image_service.show(ctxt, inst.image_ref) image_name = image.get('name', inst.image_ref) template_param_dict['image_name'] = image_name fields_string = "" for key in template_param_dict: fields_string += "\n|%s=%s" % (key, template_param_dict[key]) page_string = "{{InstanceStatus%s}}" % fields_string self._wiki_login() page = self.site.Pages[pagename] try: page.edit() page.save(page_string, "Auto update of instance info.") except (mwclient.errors.InsufficientPermission, mwclient.errors.LoginError): LOG.debug("Failed to update wiki page..." " trying to re-login next time.") self._wiki_logged_in = False
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 FLAGS.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = db.security_group_get_by_instance(ctxt, instance['id']) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group(ctxt, security_group['id']) for rule in rules: LOG.debug(_('Adding security group rule: %r'), rule) 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 version == 6 and rule.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.info('Using cidr %r', rule.cidr) args += ['-s', rule.cidr] fw_rules += [' '.join(args)] else: if rule['grantee_group']: # FIXME(jkoelker) This needs to be ported up into # the compute manager which already # has access to a nw_api handle, # and should be the only one making # making rpc calls. import nova.network nw_api = nova.network.API() for instance in rule['grantee_group']['instances']: LOG.info('instance: %r', instance) ips = [] nw_info = nw_api.get_instance_nw_info(ctxt, instance) for net in nw_info: ips.extend(net[1]['ips']) LOG.info('ips: %r', ips) for ip in ips: subrule = args + ['-s %s' % ip['ip']] fw_rules += [' '.join(subrule)] LOG.info('Using fw_rules: %r', fw_rules) ipv4_rules += ['-j $sg-fallback'] ipv6_rules += ['-j $sg-fallback'] return ipv4_rules, ipv6_rules
def get_metadata(self, address): ctxt = context.get_admin_context() search_opts = {"fixed_ip": address, "deleted": False} try: instance_ref = self.compute_api.get_all(ctxt, search_opts=search_opts) except exception.NotFound: instance_ref = None if not instance_ref: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref[0]["id"]) mpi = self._get_mpi_data(ctxt, instance_ref["project_id"]) hostname = "%s.%s" % (instance_ref["hostname"], FLAGS.dhcp_domain) host = instance_ref["host"] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host(services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info["floating_ips"] floating_ip = floating_ips and floating_ips[0] or "" ec2_id = ec2utils.id_to_ec2_id(instance_ref["id"]) image_ec2_id = ec2utils.image_ec2_id(instance_ref["image_ref"]) security_groups = db.security_group_get_by_instance(ctxt, instance_ref["id"]) security_groups = [x["name"] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { "user-data": base64.b64decode(instance_ref["user_data"]), "meta-data": { "ami-id": image_ec2_id, "ami-launch-index": instance_ref["launch_index"], "ami-manifest-path": "FIXME", "block-device-mapping": mappings, "hostname": hostname, "instance-action": "none", "instance-id": ec2_id, "instance-type": instance_ref["instance_type"]["name"], "local-hostname": hostname, "local-ipv4": address, "placement": {"availability-zone": availability_zone}, "public-hostname": hostname, "public-ipv4": floating_ip, "reservation-id": instance_ref["reservation_id"], "security-groups": security_groups, "mpi": mpi, }, } # public-keys should be in meta-data only if user specified one if instance_ref["key_name"]: data["meta-data"]["public-keys"] = { "0": {"_name": instance_ref["key_name"], "openssh-key": instance_ref["key_data"]} } for image_type in ["kernel", "ramdisk"]: if instance_ref.get("%s_id" % image_type): ec2_id = ec2utils.image_ec2_id(instance_ref["%s_id" % image_type], ec2utils.image_type(image_type)) data["meta-data"]["%s-id" % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data["ancestor-ami-ids"] = [] if False: # TODO(vish): store product codes data["product-codes"] = [] return data
def create_for_vif(self, tenant_id, instance, network, vif_chains, allow_same_net_traffic): LOG.debug('tenant_id=%r, instance=%r, network=%r, vif_chains=%r', tenant_id, instance['id'], network, vif_chains) bridge_uuid = network[0]['id'] net_cidr = network[0]['cidr'] vif_uuid = network[1]['vif_uuid'] mac = network[1]['mac'] ip = network[1]['ips'][0]['ip'] # # ingress # position = 1 in_chain = vif_chains['in'] out_chain = vif_chains['out'] # mac spoofing protection in_chain.add_rule().type('drop')\ .dl_src(mac)\ .inv_dl_src(True)\ .position(position)\ .create() position += 1 # ip spoofing protection in_chain.add_rule().type('drop')\ .nw_src_address(ip)\ .nw_src_length(32)\ .inv_nw_src(True)\ .dl_type(0x0800)\ .position(position)\ .create() position += 1 # conntrack in_chain.add_rule().type('accept')\ .match_forward_flow(True)\ .position(position)\ .create() position += 1 # # egress # ctxt = context.get_admin_context() if self.virtapi: security_groups = self.virtapi.security_group_get_by_instance( ctxt, instance) else: security_groups = db.security_group_get_by_instance( ctxt, instance['id']) position = 1 # get the port groups to match for the rule port_groups = self.mido_api.get_port_groups({'tenant_id': tenant_id}) if allow_same_net_traffic: LOG.debug('accept cidr=%r', net_cidr) nw_src_address, nw_src_length = net_cidr.split('/') out_chain.add_rule().type('accept')\ .nw_src_address(nw_src_address)\ .nw_src_length(nw_src_length)\ .position(position)\ .create() position += 1 # add rules that correspond to Nova SG for sg in security_groups: LOG.debug('security group=%r', sg['name']) if self.virtapi: rules = self.virtapi.security_group_rule_get_by_security_group( ctxt, sg) else: rules = db.security_group_rule_get_by_security_group( ctxt, sg['id']) LOG.debug('sg_id=%r', sg['id']) LOG.debug('sg_project_id=%r', sg['project_id']) LOG.debug('name=%r', sg['name']) LOG.debug('rules=%r', rules) cname = chain_name(sg['id'], sg['name']) chains = self.mido_api.get_chains({'tenant_id': tenant_id}) jump_chain_id = None for c in chains: if c.get_name() == cname: jump_chain_id = c.get_id() break # sg handler must have missed the event of creating the SG. # Now doing the equivalent as a quick workaround. if not jump_chain_id: def create_sg_resources(tenant_id, sg_id, sg_name): self.chain_manager.create_for_sg(tenant_id, sg_id, sg_name) self.pg_manager.create(tenant_id, sg_id, sg_name) create_sg_resources(tenant_id, sg['id'], sg['name']) chains = self.mido_api.get_chains({'tenant_id': tenant_id}) jump_chain_id = None for c in chains: if c.get_name() == cname: jump_chain_id = c.get_id() break assert jump_chain_id rule = out_chain.add_rule().type('jump')\ .position(position)\ .jump_chain_id(jump_chain_id)\ .jump_chain_name(cname)\ .create() position += 1 # Look for the port group that the vif should belong to for pg in port_groups: if pg.get_name() != cname: port_groups.remove(pg) # add reverse flow matching at the end out_chain.add_rule().type('accept')\ .match_return_flow(True)\ .position(position)\ .create() position += 1 # fall back DROP rule at the end except for ARP out_chain.add_rule().type('drop')\ .dl_type(0x0806)\ .inv_dl_type(True)\ .position(position)\ .create() # # Updating the vport # bridge = self.mido_api.get_bridge(bridge_uuid) bridge_port = self.mido_api.get_port(vif_uuid) LOG.debug('bridge_port=%r found', bridge_port) # set filters bridge_port.inbound_filter_id(in_chain.get_id()) bridge_port.outbound_filter_id(out_chain.get_id()) bridge_port.update() for pg in port_groups: pg.add_port_group_port().port_id(bridge_port.get_id()).create()
def instance_rules(self, instance, network_info): # make sure this is legacy nw_info network_info = self._handle_network_info_model(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 FLAGS.allow_same_net_traffic: self._do_project_network_rules(ipv4_rules, ipv6_rules, network_info) # We wrap these in FLAGS.use_ipv6 because they might cause # a DB lookup. The other ones are just list operations, so # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses self._do_ra_rules(ipv6_rules, network_info) security_groups = db.security_group_get_by_instance(ctxt, instance["id"]) # then, security group chains and rules for security_group in security_groups: rules = db.security_group_rule_get_by_security_group(ctxt, security_group["id"]) 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"]: # FIXME(jkoelker) This needs to be ported up into # the compute manager which already # has access to a nw_api handle, # and should be the only one making # making rpc calls. nw_api = network.API() for instance in rule["grantee_group"]["instances"]: nw_info = nw_api.get_instance_nw_info(ctxt, 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