def test_creates_network_sized_v4_subnet_in_melange(self):
        self.flags(use_ipv6=False)
        melange_client.create_block(IgnoreArg(), "10.1.1.0/26", "project1",
                                    None, None)
        self.mox.ReplayAll()

        self._create_quantum_manager_network(cidr="10.1.1.0/24",
                                             num_networks=1, network_size=64,
                                             project_id="project1")
    def test_create_v4block_with_dns(self):
        self.flags(use_ipv6=False)
        melange_client.create_block(IgnoreArg(), "10.1.1.0/26", "project1",
                                    "10.2.3.4", "10.3.4.5")
        self.mox.ReplayAll()

        self._create_quantum_manager_network(cidr="10.1.1.0/24",
                                             num_networks=1, network_size=64,
                                             project_id="project1",
                                             dns1="10.2.3.4", dns2="10.3.4.5")
    def test_create_block_without_project_id(self):
        network_id = "network123"
        cidr = "10.0.0.0/24"
        mock_client = setup_mock_client(self.mox)
        req_body = dict(ip_block=dict(cidr=cidr,
                                      network_id=network_id,
                                      type='private',
                                      dns1=None, dns2=None))
        mock_client.post("/v0.1/ipam/ip_blocks",
                         body=json.dumps(req_body),
                         headers=json_content_type()).AndReturn(None)

        self.mox.ReplayAll()

        melange_client.create_block(network_id, cidr, project_id=None)
    def test_create_block_for_a_given_project_id(self):
        network_id = "netwok123"
        cidr = "10.0.0.0/24"
        project_id = "project1"
        dns1 = "10.1.2.3"
        dns2 = "10.2.3.4"
        mock_client = setup_mock_client(self.mox)
        req_body = dict(ip_block=dict(cidr=cidr,
                                      network_id=network_id,
                                      type='private',
                                      dns1=dns1, dns2=dns2))
        mock_client.post("/v0.1/ipam/tenants/project1/ip_blocks",
                         body=json.dumps(req_body),
                         headers=json_content_type()).AndReturn(None)

        self.mox.ReplayAll()

        melange_client.create_block(network_id, cidr, project_id=project_id,
                                    dns1=dns1, dns2=dns2)
    def test_creates_multiple_melange_blocks_for_a_single_network(self):
        self.flags(use_ipv6=True)
        melange_client.create_block(IgnoreArg(), "10.1.0.0/24",
                                    "project1", None, None)
        melange_client.create_block(IgnoreArg(), "fe::/64",
                                    "project1", None, None)

        melange_client.create_block(IgnoreArg(), "10.1.1.0/24",
                                    "project1", None, None)
        melange_client.create_block(IgnoreArg(), "fe:0:0:1::/64",
                                    "project1", None, None)

        self.mox.ReplayAll()

        self._create_quantum_manager_network(cidr="10.1.0.0/20",
                                             num_networks=2, network_size=256,
                                             cidr_v6="fe::/60",
                                             project_id="project1")
    def test_always_creates_64_prefix_len_ipv6_melange_blocks(self):
        self.flags(use_ipv6=True)

        melange_client.create_block(IgnoreArg(), "10.1.1.0/26",
                                    "project1", None, None)
        melange_client.create_block(IgnoreArg(), "fe::/64",
                                    "project1", None, None)

        melange_client.create_block(IgnoreArg(), "10.1.1.0/26",
                                    "project1", None, None)
        melange_client.create_block(IgnoreArg(), "c0::/64",
                                    "project1", None, None)

        self.mox.ReplayAll()

        self._create_quantum_manager_network(cidr="10.1.1.0/24",
                                             num_networks=1, network_size=64,
                                             cidr_v6="fe::/60",
                                             project_id="project1")

        self._create_quantum_manager_network(cidr="10.1.1.0/24",
                                             num_networks=1, network_size=64,
                                             cidr_v6="fe::/10",
                                             project_id="project1")
    def create_networks(self, context, label, cidr, multi_host, num_networks,
                        network_size, cidr_v6, gateway_v6, bridge,
                        bridge_interface, dns1=None, dns2=None, **kwargs):
        """Create networks based on parameters."""

        # FIXME: enforce that this is called only for a single network

        # FIXME: decomp out most of this function, likely by calling
        # FlatManager.create_networks, then once that is complete,
        # calling Quantum and patching up the "bridge" field in the newly
        # created network row.

        if "priority" not in kwargs:
            raise Exception("QuantumManager requires each network to"
                                            " have a priority")

        fixed_net = netaddr.IPNetwork(cidr)
        if FLAGS.use_ipv6:
            fixed_net_v6 = netaddr.IPNetwork(cidr_v6)
            significant_bits_v6 = 64
            network_size_v6 = 1 << 64

        for index in range(num_networks):
            start = index * network_size
            significant_bits = 32 - int(math.log(network_size, 2))
            cidr = '%s/%s' % (fixed_net[start], significant_bits)
            project_net = netaddr.IPNetwork(cidr)
            net = {}
            net['bridge'] = bridge
            net['bridge_interface'] = bridge_interface
            net['multi_host'] = multi_host
            net['dhcp_start'] = str(project_net[2])
            net['priority'] = int(kwargs["priority"])
            if kwargs["project_id"] not in [None, "0"]:
                net['project_id'] = kwargs["project_id"]
            if num_networks > 1:
                net['label'] = '%s_%d' % (label, index)
            else:
                net['label'] = label

            if FLAGS.use_ipv6:
                start_v6 = index * network_size_v6
                cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6],
                                     significant_bits_v6)

            if kwargs.get('vpn', False):
                # this bit here is for vlan-manager
                vlan = kwargs['vlan_start'] + index
                net['vpn_private_address'] = str(project_net[2])
                net['dhcp_start'] = str(project_net[3])
                net['vlan'] = vlan
                net['bridge'] = 'br%s' % vlan

                # NOTE(vish): This makes ports unique accross the cloud, a more
                #             robust solution would be to make them uniq per ip
                net['vpn_public_port'] = kwargs['vpn_start'] + index

            # Populate the quantum network uuid if we have it.  We're
            # currently using the bridge column for this since we don't have
            # another place to put it.
            existing_id = kwargs.get("existing_net_id", None)
            if existing_id:
                try:
                    network_exists = quantum.get_network(
                      FLAGS.quantum_default_tenant_id, existing_id)
                except:
                    txt = "Unable to find quantum network with uuid: %s" % \
                      (existing_id)
                    raise Exception(txt)
                net["bridge"] = existing_id
            else:
                # If the uuid wasn't provided and the project is specified
                # then we should try to create this network via quantum.

                tenant_id = kwargs["project_id"] or \
                            FLAGS.quantum_default_tenant_id
                quantum_net_id = quantum.create_network(tenant_id, label)
                net["bridge"] = quantum_net_id
                LOG.info(_("Quantum network uuid for network"
                           " \"%(label)s\": %(quantum_net_id)s") % locals())

            network = self.db.network_create_safe(context, net)
            project_id = kwargs.get("project_id", None)
            if project_id == '0':
                project_id = None

            if cidr:
                melange.create_block(network['id'], cidr, project_id,
                                     dns1, dns2)
            if cidr_v6:
                melange.create_block(network['id'], cidr_v6, project_id,
                                     dns1, dns2)