Exemple #1
0
def check_subnet_ip_count(conf, cidr, num_instances):
    """Check the given subnet and configured rac subnet have enough IPs."""
    subnet_manager = rac_utils.RACPublicSubnetManager(cidr)
    if num_instances > subnet_manager.max_instances:
        raise exception.BadValue(_(
            "Not enough IPs available in the specified public subnet."))
    interconnect_manager = rac_utils.CommonSubnetManager(
        conf.interconnect_subnet_cidr)
    if num_instances > interconnect_manager.max_instances:
        raise exception.BadValue(_("Not enough IPs available in the configured "
                                   "private RAC interconnect subnet."))
Exemple #2
0
def check_subnet(conf, driver, num_instances, subnet_id):
    try:
        subnet = driver.get_subnet_by_id(subnet_id)
    except exception.TroveError:
        raise exception.BadValue(_("Public subnet is not valid."))
    check_subnet_ip_count(conf, subnet['cidr'], num_instances)
    return subnet
Exemple #3
0
def check_subnetpool(conf, driver, num_instances, subnetpool_id, prefixlen):
    try:
        subnetpool = driver.get_subnetpool_by_id(subnetpool_id)
    except exception.TroveError:
        raise exception.BadValue(_("Public subnet pool is not valid."))
    prefix_len = determine_subnet_prefix_len(conf, subnetpool, prefixlen)
    pmin = int(subnetpool['min_prefixlen'])
    pmax = int(subnetpool['max_prefixlen'])
    if prefix_len < pmin or prefix_len > pmax:
        raise exception.BadValue(_(
            "Subnet prefix length {plen} is outside of pool's "
            "range {pmin}-{pmax}.").format(
            plen=prefix_len, pmin=pmin, pmax=pmax))
    ipnet = netaddr.IPNetwork(subnetpool['prefixes'][0])
    ipnet.prefixlen = prefix_len
    check_subnet_ip_count(conf, str(ipnet.cidr), num_instances)
    return subnetpool
Exemple #4
0
def check_router(driver, router_id):
    if not router_id:
        raise exception.BadRequest(_(
            "Network information missing 'router'. To use a subnet pool a "
            "router id must be given."))
    try:
        driver.get_router_by_id(router_id)
    except exception.TroveError:
        raise exception.BadValue(_("Router is not valid."))
Exemple #5
0
def check_network(driver, network_id):
    if not network_id:
        raise exception.BadRequest(_(
            "Network information missing 'id'. To use a subnet pool a network "
            "id must be given."))
    try:
        network = driver.get_network_by_id(network_id)
    except exception.TroveError:
        raise exception.BadValue(_("Public network is not valid."))
    return network
Exemple #6
0
def check_storage_info(properties):
    """Check the storage information provided by the user."""
    storage_type = properties.get('storage_type')
    if not storage_type:
        raise exception.BadRequest(_("Missing storage type."))
    storage = {'type': storage_type, 'data': dict()}
    if storage_type == 'nfs':
        def _check_mount(name):
            value = properties.get(name)
            if not value or not re.match(r'\S+:\S+', str(value)):
                raise exception.BadRequest(_(
                    "Invalid or missing mount {name}. "
                    "Specify mount values for votedisk_mount, "
                    "registry_mount, and database_mount in the format "
                    "'host:path'.".format(name=name)))
            storage['data'][name] = value

        for mount in ['votedisk_mount', 'registry_mount', 'database_mount']:
            _check_mount(mount)
    else:
        raise exception.BadValue(_("Unsupported cluster storage "
                                   "type ").format(t=storage_type))
    return storage
Exemple #7
0
    def create(cls, context, name, datastore, datastore_version,
               instances, extended_properties, locality):
        nova_client = remote.create_nova_client(context)
        network_driver = (importutils.import_class(
            CONF.network_driver))(context, None)
        ds_conf = CONF.get(datastore_version.manager)
        num_instances = len(instances)

        # Run checks first
        if not network_driver.subnet_support:
            raise exception.TroveError(_(
                "The configured network driver does not support subnet "
                "management. This is required for Oracle RAC clusters."))

        quota.check_quotas(context.tenant, {'instances': num_instances})
        for instance in instances:
            if not instance.get('flavor_id'):
                raise exception.BadRequest(_("Missing required flavor_id."))
            try:
                nova_client.flavors.get(instance['flavor_id'])
            except nova_exceptions.NotFound:
                raise exception.FlavorNotFound(uuid=instance['flavor_id'])
            if instance.get('volume_size'):
                raise exception.VolumeNotSupported()
            if instance.get('region_name'):
                raise exception.BadRequest(_("Instance region_name option not "
                                             "supported."))

        database = extended_properties.get('database')
        if not database:
            raise exception.BadRequest(_("Missing database name."))
        if len(database) > 8:
            raise exception.BadValue(_("Database name greater than 8 chars."))
        storage_info = check_storage_info(extended_properties)
        subnet, subnetpool, network = check_public_network_info(
            ds_conf, network_driver, num_instances, extended_properties)

        ssh_pem, ssh_pub = crypto_utils.generate_ssh_keys()

        sys_password = utils.generate_random_password(
            datastore=datastore.name)
        admin_password = utils.generate_random_password(
            datastore=datastore.name)

        # Create the cluster
        db_info = models.DBCluster.create(
            name=name, tenant_id=context.tenant,
            datastore_version_id=datastore_version.id,
            task_status=tasks.ClusterTasks.BUILDING_INITIAL)

        if not subnet:
            LOG.debug("Creating RAC public subnet on network {net} from "
                      "pool {pool}".format(net=network['id'],
                                           pool=subnetpool['id']))
            subnet = create_public_subnet_from_pool(
                ds_conf, network_driver, db_info.id, subnetpool, network,
                extended_properties.get('router'),
                extended_properties.get('prefixlen'))
            LOG.debug("Created subnet {sub} with CIDR {cidr}".format(
                sub=subnet['id'], cidr=subnet['cidr']))

        interconnect_network, interconnect_subnet = create_interconnect(
            ds_conf, network_driver, db_info.id)
        LOG.debug("Created interconnect network {net} with subnet "
                  "{sub}".format(net=interconnect_network['id'],
                                 sub=interconnect_subnet['id']))

        public_subnet_manager = rac_utils.RACPublicSubnetManager(
            subnet['cidr'])
        interconnect_subnet_manager = rac_utils.CommonSubnetManager(
            interconnect_subnet['cidr'])

        subnet = configure_public_subnet(
            ds_conf, network_driver, db_info.id, subnet,
            public_subnet_manager.allocation_pool)
        LOG.debug("RAC public subnet ({sub_id}) info: name='{name}', scans="
                  "{scans}".format(sub_id=subnet['id'], name=subnet['name'],
                                   scans=public_subnet_manager.scan_list))

        cluster_config = {
            'id': db_info.id,
            'instance_type': 'node',
            'storage': storage_info,
            'ssh_pem': ssh_pem,
            'ssh_pub': ssh_pub,
            'database': database,
            'sys_password': sys_password,
            'admin_password': admin_password}

        vips = (public_subnet_manager.scan_list +
                [public_subnet_manager.instance_vip(i)
                 for i in range(len(instances))])

        for i, instance in enumerate(instances):
            instance_name = rac_utils.make_instance_hostname(name, i)
            nics = instance.get('nics') or []
            public_port_name = rac_utils.make_object_name(
                ds_conf, ['public', 'port', str(i + 1)], db_info.id)
            public_port = create_port(
                network_driver, public_port_name, i,
                subnet, public_subnet_manager, vips=vips)
            interconnect_port_name = rac_utils.make_object_name(
                ds_conf, ['interconnect', 'port', str(i + 1)], db_info.id)
            interconnect_port = create_port(
                network_driver, interconnect_port_name, i,
                interconnect_subnet, interconnect_subnet_manager)
            nics.append({'port-id': public_port['id']})
            nics.append({'port-id': interconnect_port['id']})
            LOG.debug("Creating instance {name} with public ip {pub} and "
                      "interconnect ip {int}".format(
                        name=instance_name,
                        pub=public_port['fixed_ips'][0]['ip_address'],
                        int=interconnect_port['fixed_ips'][0]['ip_address']))
            inst_models.Instance.create(
                context,
                instance_name,
                instance['flavor_id'],
                datastore_version.image_id,
                [], [], datastore,
                datastore_version,
                None, None,
                availability_zone=instance.get('availability_zone'),
                nics=nics,
                cluster_config=cluster_config,
                modules=instance.get('modules'),
                locality=locality)

        task_api.load(context, datastore_version.manager).create_cluster(
            db_info.id)

        return OracleRACCluster(context, db_info, datastore, datastore_version)