Example #1
0
 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")
Example #2
0
 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')
Example #3
0
 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')
Example #4
0
 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"])
Example #5
0
 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'])
Example #7
0
File: base.py Project: nati/nova
    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
Example #8
0
    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 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)
Example #10
0
    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)
Example #11
0
 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'])
Example #12
0
    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"])))}
Example #13
0
 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'])
Example #14
0
    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)
Example #15
0
    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'])))}
Example #16
0
    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
Example #17
0
File: base.py Project: judu/nova
    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
Example #18
0
    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()
Example #19
0
 def security_group_get_by_instance(self, context, instance_uuid):
     return db.security_group_get_by_instance(context, instance_uuid)
Example #20
0
    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
Example #21
0
    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
Example #22
0
    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))
Example #24
0
    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
Example #25
0
    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
Example #26
0
 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)
Example #27
0
    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
Example #28
0
 def get_by_instance(cls, context, instance):
     return _make_secgroup_list(context, cls(),
                                db.security_group_get_by_instance(
                                    context, instance.uuid))
Example #29
0
 def security_group_get_by_instance(self, context, instance):
     return db.security_group_get_by_instance(context, instance['id'])
Example #30
0
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')
Example #31
0
    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
Example #32
0
    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
Example #33
0
File: fake.py Project: gajen/nova
 def security_group_get_by_instance(self, context, instance_uuid):
     return db.security_group_get_by_instance(context, instance_uuid)
Example #34
0
 def security_group_get_by_instance(self, context, instance):
     return db.security_group_get_by_instance(context, instance['id'])
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')
Example #36
0
    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
Example #37
0
    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
Example #39
0
    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
Example #41
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 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
Example #42
0
    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()
Example #44
0
 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)
Example #45
0
    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