Ejemplo n.º 1
0
 def _check_instances(context, instances, datastore_version,
                      allowed_instance_count=None):
     instance_count = len(instances)
     if allowed_instance_count:
         if instance_count not in allowed_instance_count:
             raise exception.ClusterNumInstancesNotSupported(
                 num_instances=allowed_instance_count
             )
     flavor_ids = [instance['flavor_id'] for instance in instances]
     if len(set(flavor_ids)) != 1:
         raise exception.ClusterFlavorsNotEqual()
     flavor_id = flavor_ids[0]
     nova_client = clients.create_nova_client(context)
     try:
         flavor = nova_client.flavors.get(flavor_id)
     except nova_exceptions.NotFound:
         raise exception.FlavorNotFound(uuid=flavor_id)
     mongo_conf = CONF.get(datastore_version.manager)
     volume_sizes = [instance['volume_size'] for instance in instances
                     if instance.get('volume_size', None)]
     if mongo_conf.volume_support:
         if len(volume_sizes) != instance_count:
             raise exception.ClusterVolumeSizeRequired()
         if len(set(volume_sizes)) != 1:
             raise exception.ClusterVolumeSizesNotEqual()
         volume_size = volume_sizes[0]
         models.validate_volume_size(volume_size)
     else:
         # TODO(amcreynolds): is ephemeral possible for mongodb clusters?
         if len(volume_sizes) > 0:
             raise exception.VolumeNotSupported()
         ephemeral_support = mongo_conf.device_path
         if ephemeral_support and flavor.ephemeral == 0:
             raise exception.LocalStorageNotSpecified(flavor=flavor_id)
Ejemplo n.º 2
0
    def _validate_cluster_instances(context, instances, datastore,
                                    datastore_version):
        """Validate the flavor and volume"""
        ds_conf = CONF.get(datastore_version.manager)
        num_instances = len(instances)

        # Check number of instances is at least min_cluster_member_count
        if num_instances < ds_conf.min_cluster_member_count:
            raise exception.ClusterNumInstancesNotLargeEnough(
                num_instances=ds_conf.min_cluster_member_count)

        # Checking flavors and get delta for quota check
        flavor_ids = [instance['flavor_id'] for instance in instances]
        if len(set(flavor_ids)) != 1:
            raise exception.ClusterFlavorsNotEqual()
        flavor_id = flavor_ids[0]
        nova_client = remote.create_nova_client(context)
        try:
            flavor = nova_client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)
        deltas = {'instances': num_instances}

        # Checking volumes and get delta for quota check
        volume_sizes = [instance['volume_size'] for instance in instances
                        if instance.get('volume_size', None)]
        volume_size = None
        if ds_conf.volume_support:
            if len(volume_sizes) != num_instances:
                raise exception.ClusterVolumeSizeRequired()
            if len(set(volume_sizes)) != 1:
                raise exception.ClusterVolumeSizesNotEqual()
            volume_size = volume_sizes[0]
            cluster_models.validate_volume_size(volume_size)
            deltas['volumes'] = volume_size * num_instances
        else:
            if len(volume_sizes) > 0:
                raise exception.VolumeNotSupported()
            ephemeral_support = ds_conf.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        # quota check
        check_quotas(context.tenant, deltas)

        # Checking networks are same for the cluster
        instance_nics = []
        for instance in instances:
            nics = instance.get('nics')
            if nics:
                instance_nics.append(nics[0].get('net-id'))
        if len(set(instance_nics)) > 1:
            raise exception.ClusterNetworksNotEqual()
        if not instance_nics:
            return
        instance_nic = instance_nics[0]
        try:
            nova_client.networks.get(instance_nic)
        except nova_exceptions.NotFound:
            raise exception.NetworkNotFound(uuid=instance_nic)
Ejemplo n.º 3
0
def assert_same_instance_volumes(instances, required_size=None):
    """Verify that all instances have the same volume size (size = 0 if there
    is not a Trove volume for the instance).

    :param required_size              Size in GB or 0 if there should be no
                                      attached volumes.
    :type required_size               int
    """
    sizes = {instance.get('volume_size', 0) for instance in instances}
    if len(sizes) != 1 or (required_size is not None
                           and required_size not in sizes):
        raise exception.ClusterVolumeSizesNotEqual()
Ejemplo n.º 4
0
Archivo: api.py Proyecto: flg77/trove
    def create(cls, context, name, datastore, datastore_version, instances):

        # TODO(amcreynolds): consider moving into CONF and even supporting
        # TODO(amcreynolds): an array of values, e.g. [3, 5, 7]
        # TODO(amcreynolds): or introduce a min/max num_instances and set
        # TODO(amcreynolds): both to 3
        num_instances = len(instances)
        if num_instances != 3:
            raise exception.ClusterNumInstancesNotSupported(num_instances=3)

        flavor_ids = [instance['flavor_id'] for instance in instances]
        if len(set(flavor_ids)) != 1:
            raise exception.ClusterFlavorsNotEqual()
        flavor_id = flavor_ids[0]
        nova_client = remote.create_nova_client(context)
        try:
            flavor = nova_client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)
        mongo_conf = CONF.get(datastore_version.manager)
        num_configsvr = mongo_conf.num_config_servers_per_cluster
        num_mongos = mongo_conf.num_query_routers_per_cluster
        delta_instances = num_instances + num_configsvr + num_mongos
        deltas = {'instances': delta_instances}

        volume_sizes = [
            instance['volume_size'] for instance in instances
            if instance.get('volume_size', None)
        ]
        volume_size = None
        if mongo_conf.volume_support:
            if len(volume_sizes) != num_instances:
                raise exception.ClusterVolumeSizeRequired()
            if len(set(volume_sizes)) != 1:
                raise exception.ClusterVolumeSizesNotEqual()
            volume_size = volume_sizes[0]
            models.validate_volume_size(volume_size)
            # TODO(amcreynolds): for now, mongos+configsvr same flavor+disk
            deltas['volumes'] = volume_size * delta_instances
        else:
            # TODO(amcreynolds): is ephemeral possible for mongodb clusters?
            if len(volume_sizes) > 0:
                raise exception.VolumeNotSupported()
            ephemeral_support = mongo_conf.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        check_quotas(context.tenant, deltas)

        db_info = models.DBCluster.create(
            name=name,
            tenant_id=context.tenant,
            datastore_version_id=datastore_version.id,
            task_status=ClusterTasks.BUILDING_INITIAL)

        replica_set_name = "rs1"

        member_config = {
            "id": db_info.id,
            "shard_id": utils.generate_uuid(),
            "instance_type": "member",
            "replica_set_name": replica_set_name
        }
        for i in range(1, num_instances + 1):
            instance_name = "%s-%s-%s" % (name, replica_set_name, str(i))
            inst_models.Instance.create(context,
                                        instance_name,
                                        flavor_id,
                                        datastore_version.image_id, [], [],
                                        datastore,
                                        datastore_version,
                                        volume_size,
                                        None,
                                        availability_zone=None,
                                        nics=None,
                                        configuration_id=None,
                                        cluster_config=member_config)

        configsvr_config = {"id": db_info.id, "instance_type": "config_server"}
        for i in range(1, num_configsvr + 1):
            instance_name = "%s-%s-%s" % (name, "configsvr", str(i))
            inst_models.Instance.create(context,
                                        instance_name,
                                        flavor_id,
                                        datastore_version.image_id, [], [],
                                        datastore,
                                        datastore_version,
                                        volume_size,
                                        None,
                                        availability_zone=None,
                                        nics=None,
                                        configuration_id=None,
                                        cluster_config=configsvr_config)

        mongos_config = {"id": db_info.id, "instance_type": "query_router"}
        for i in range(1, num_mongos + 1):
            instance_name = "%s-%s-%s" % (name, "mongos", str(i))
            inst_models.Instance.create(context,
                                        instance_name,
                                        flavor_id,
                                        datastore_version.image_id, [], [],
                                        datastore,
                                        datastore_version,
                                        volume_size,
                                        None,
                                        availability_zone=None,
                                        nics=None,
                                        configuration_id=None,
                                        cluster_config=mongos_config)

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

        return MongoDbCluster(context, db_info, datastore, datastore_version)
Ejemplo n.º 5
0
    def create(cls, context, name, datastore, datastore_version, instances,
               extended_properties):
        LOG.debug("Initiating cluster creation.")
        vertica_conf = CONF.get(datastore_version.manager)
        num_instances = len(instances)

        # Matching number of instances with configured cluster_member_count
        if num_instances != vertica_conf.cluster_member_count:
            raise exception.ClusterNumInstancesNotSupported(
                num_instances=vertica_conf.cluster_member_count)

        # Checking flavors
        flavor_ids = [instance['flavor_id'] for instance in instances]
        if len(set(flavor_ids)) != 1:
            raise exception.ClusterFlavorsNotEqual()
        flavor_id = flavor_ids[0]
        nova_client = remote.create_nova_client(context)
        try:
            flavor = nova_client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)
        deltas = {'instances': num_instances}

        # Checking volumes
        volume_sizes = [
            instance['volume_size'] for instance in instances
            if instance.get('volume_size', None)
        ]
        volume_size = None
        if vertica_conf.volume_support:
            if len(volume_sizes) != num_instances:
                raise exception.ClusterVolumeSizeRequired()
            if len(set(volume_sizes)) != 1:
                raise exception.ClusterVolumeSizesNotEqual()
            volume_size = volume_sizes[0]
            models.validate_volume_size(volume_size)
            deltas['volumes'] = volume_size * num_instances
        else:
            if len(volume_sizes) > 0:
                raise exception.VolumeNotSupported()
            ephemeral_support = vertica_conf.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        check_quotas(context.tenant, deltas)

        nics = [instance.get('nics', None) for instance in instances]

        azs = [
            instance.get('availability_zone', None) for instance in instances
        ]

        # Updating Cluster Task
        db_info = models.DBCluster.create(
            name=name,
            tenant_id=context.tenant,
            datastore_version_id=datastore_version.id,
            task_status=ClusterTasks.BUILDING_INITIAL)

        # Creating member instances
        for i in range(0, num_instances):
            if i == 0:
                member_config = {"id": db_info.id, "instance_type": "master"}
            else:
                member_config = {"id": db_info.id, "instance_type": "member"}
            instance_name = "%s-member-%s" % (name, str(i + 1))
            inst_models.Instance.create(context,
                                        instance_name,
                                        flavor_id,
                                        datastore_version.image_id, [], [],
                                        datastore,
                                        datastore_version,
                                        volume_size,
                                        None,
                                        nics=nics[i],
                                        availability_zone=azs[i],
                                        configuration_id=None,
                                        cluster_config=member_config)

        # Calling taskmanager to further proceed for cluster-configuration
        task_api.load(context,
                      datastore_version.manager).create_cluster(db_info.id)

        return VerticaCluster(context, db_info, datastore, datastore_version)
Ejemplo n.º 6
0
    def _create_instances(context,
                          db_info,
                          datastore,
                          datastore_version,
                          instances,
                          extended_properties,
                          locality,
                          new_cluster=True):
        vertica_conf = CONF.get(datastore_version.manager)
        num_instances = len(instances)

        existing = inst_models.DBInstance.find_all(cluster_id=db_info.id).all()
        num_existing = len(existing)

        # Matching number of instances with configured cluster_member_count
        if (new_cluster
                and num_instances != vertica_conf.cluster_member_count):
            raise exception.ClusterNumInstancesNotSupported(
                num_instances=vertica_conf.cluster_member_count)

        # Checking flavors
        flavor_ids = [instance['flavor_id'] for instance in instances]
        if len(set(flavor_ids)) != 1:
            raise exception.ClusterFlavorsNotEqual()
        flavor_id = flavor_ids[0]
        nova_client = remote.create_nova_client(context)
        try:
            flavor = nova_client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)
        deltas = {'instances': num_instances}

        # Checking volumes
        volume_sizes = [
            instance['volume_size'] for instance in instances
            if instance.get('volume_size', None)
        ]
        volume_size = None
        if vertica_conf.volume_support:
            if len(volume_sizes) != num_instances:
                raise exception.ClusterVolumeSizeRequired()
            if len(set(volume_sizes)) != 1:
                raise exception.ClusterVolumeSizesNotEqual()
            volume_size = volume_sizes[0]
            models.validate_volume_size(volume_size)
            deltas['volumes'] = volume_size * num_instances
        else:
            if len(volume_sizes) > 0:
                raise exception.VolumeNotSupported()
            ephemeral_support = vertica_conf.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        check_quotas(context.tenant, deltas)

        nics = [instance.get('nics', None) for instance in instances]

        azs = [
            instance.get('availability_zone', None) for instance in instances
        ]

        # Creating member instances
        minstances = []
        for i in range(0, num_instances):
            if i == 0 and new_cluster:
                member_config = {"id": db_info.id, "instance_type": "master"}
            else:
                member_config = {"id": db_info.id, "instance_type": "member"}
            instance_name = "%s-member-%s" % (db_info.name,
                                              str(i + num_existing + 1))
            minstances.append(
                inst_models.Instance.create(context,
                                            instance_name,
                                            flavor_id,
                                            datastore_version.image_id, [], [],
                                            datastore,
                                            datastore_version,
                                            volume_size,
                                            None,
                                            nics=nics[i],
                                            availability_zone=azs[i],
                                            configuration_id=None,
                                            cluster_config=member_config,
                                            locality=locality))
        return minstances
Ejemplo n.º 7
0
    def create(cls, context, name, datastore, datastore_version,
               instances, extended_properties, locality):

        # TODO(amcreynolds): consider moving into CONF and even supporting
        # TODO(amcreynolds): an array of values, e.g. [3, 5, 7]
        # TODO(amcreynolds): or introduce a min/max num_instances and set
        # TODO(amcreynolds): both to 3
        num_instances = len(instances)
        if num_instances != 3:
            raise exception.ClusterNumInstancesNotSupported(num_instances=3)

        flavor_ids = [instance['flavor_id'] for instance in instances]
        if len(set(flavor_ids)) != 1:
            raise exception.ClusterFlavorsNotEqual()
        flavor_id = flavor_ids[0]
        nova_client = remote.create_nova_client(context)
        try:
            flavor = nova_client.flavors.get(flavor_id)
        except nova_exceptions.NotFound:
            raise exception.FlavorNotFound(uuid=flavor_id)
        mongo_conf = CONF.get(datastore_version.manager)
        num_configsvr = (1 if mongo_conf.num_config_servers_per_cluster == 1
                         else 3)
        num_mongos = mongo_conf.num_query_routers_per_cluster
        delta_instances = num_instances + num_configsvr + num_mongos
        deltas = {'instances': delta_instances}

        volume_sizes = [instance['volume_size'] for instance in instances
                        if instance.get('volume_size', None)]
        volume_size = None
        if mongo_conf.volume_support:
            if len(volume_sizes) != num_instances:
                raise exception.ClusterVolumeSizeRequired()
            if len(set(volume_sizes)) != 1:
                raise exception.ClusterVolumeSizesNotEqual()
            volume_size = volume_sizes[0]
            models.validate_volume_size(volume_size)
            # TODO(amcreynolds): for now, mongos+configsvr same flavor+disk
            deltas['volumes'] = volume_size * delta_instances
        else:
            # TODO(amcreynolds): is ephemeral possible for mongodb clusters?
            if len(volume_sizes) > 0:
                raise exception.VolumeNotSupported()
            ephemeral_support = mongo_conf.device_path
            if ephemeral_support and flavor.ephemeral == 0:
                raise exception.LocalStorageNotSpecified(flavor=flavor_id)

        check_quotas(context.tenant, deltas)

        nics = [instance.get('nics', None) for instance in instances]
        nic = nics[0]
        for n in nics[1:]:
            if n != nic:
                raise ValueError(_('All cluster nics must be the same. '
                                   '%(nic)s != %(n)s')
                                 % {'nic': nic, 'n': n})

        azs = [instance.get('availability_zone', None)
               for instance in instances]

        regions = [instance.get('region_name', None)
                   for instance in instances]

        db_info = models.DBCluster.create(
            name=name, tenant_id=context.tenant,
            datastore_version_id=datastore_version.id,
            task_status=ClusterTasks.BUILDING_INITIAL)

        replica_set_name = "rs1"

        member_config = {"id": db_info.id,
                         "shard_id": utils.generate_uuid(),
                         "instance_type": "member",
                         "replica_set_name": replica_set_name}

        configsvr_config = {"id": db_info.id,
                            "instance_type": "config_server"}

        mongos_config = {"id": db_info.id,
                         "instance_type": "query_router"}

        if mongo_conf.cluster_secure:
            cluster_key = base64.b64encode(utils.generate_random_password())
            member_config['key'] = cluster_key
            configsvr_config['key'] = cluster_key
            mongos_config['key'] = cluster_key

        for i in range(num_instances):
            instance_name = "%s-%s-%s" % (name, replica_set_name, str(i + 1))
            inst_models.Instance.create(context, instance_name,
                                        flavor_id,
                                        datastore_version.image_id,
                                        [], [], datastore,
                                        datastore_version,
                                        volume_size, None,
                                        availability_zone=azs[i],
                                        nics=nic,
                                        configuration_id=None,
                                        cluster_config=member_config,
                                        modules=instances[i].get('modules'),
                                        region_name=regions[i],
                                        locality=locality)

        for i in range(num_configsvr):
            instance_name = "%s-%s-%s" % (name, "configsvr", str(i + 1))
            inst_models.Instance.create(context, instance_name,
                                        flavor_id,
                                        datastore_version.image_id,
                                        [], [], datastore,
                                        datastore_version,
                                        volume_size, None,
                                        availability_zone=azs[i %
                                                              num_instances],
                                        nics=nic,
                                        configuration_id=None,
                                        cluster_config=configsvr_config,
                                        region_name=regions[i % num_instances],
                                        locality=locality)

        for i in range(num_mongos):
            instance_name = "%s-%s-%s" % (name, "mongos", str(i + 1))
            inst_models.Instance.create(context, instance_name,
                                        flavor_id,
                                        datastore_version.image_id,
                                        [], [], datastore,
                                        datastore_version,
                                        volume_size, None,
                                        availability_zone=azs[i %
                                                              num_instances],
                                        nics=nic,
                                        configuration_id=None,
                                        cluster_config=mongos_config,
                                        region_name=regions[i % num_instances],
                                        locality=locality)

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

        return MongoDbCluster(context, db_info, datastore, datastore_version)