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."))
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
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
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."))
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
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
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)