f858e537dd
This patch provides the scheduler support to filter share backends matching replication capabilities reported by the hosts and the replication_type extra_spec provided via the share_type during share creation. It also adds wsgi routes, API endpoints and driver entry routines to support the actions: list, show, create, delete and promote share replicas. It augments the ShareInstance DB model with a 'replica_state' attribute and the Share DB Model with 'replication_type' attribute to support these workflows. Replica states are periodically updated from the respective backends that the replicas are created on. APIImpact Impact on existing APIs: In Microversion 2.11, the /shares APIs return 2 additional fields during index and show calls for each share: 'has_replicas' and 'replication_type'. Similarly, the field 'replica_state' is added to the API response for /share-instances. Also, deletion of a share that has replicas is forbidden, returning error code 403. DocImpact Co-Authored-By: Alex Meade <mr.alex.meade@gmail.com> Implements: blueprint manila-share-replication Change-Id: I10515d55b1291c34777a31d8c6a3a1954f551235
190 lines
5.7 KiB
Python
190 lines
5.7 KiB
Python
# Copyright 2015 Mirantis Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import copy
|
|
|
|
from manila.common import constants
|
|
from manila import context
|
|
from manila import db
|
|
|
|
|
|
def _create_db_row(method, default_values, custom_values):
|
|
override_defaults = custom_values.pop('override_defaults', None)
|
|
if override_defaults:
|
|
default_values = custom_values
|
|
else:
|
|
default_values.update(copy.deepcopy(custom_values))
|
|
return method(context.get_admin_context(), default_values)
|
|
|
|
|
|
def create_consistency_group(**kwargs):
|
|
"""Create a consistency group object."""
|
|
cg = {
|
|
'share_network_id': None,
|
|
'share_server_id': None,
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'status': constants.STATUS_CREATING,
|
|
'host': 'fake_host'
|
|
}
|
|
return _create_db_row(db.consistency_group_create, cg, kwargs)
|
|
|
|
|
|
def create_cgsnapshot(cg_id, **kwargs):
|
|
"""Create a cgsnapshot object."""
|
|
snapshot = {
|
|
'consistency_group_id': cg_id,
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'status': constants.STATUS_CREATING,
|
|
}
|
|
return _create_db_row(db.cgsnapshot_create, snapshot, kwargs)
|
|
|
|
|
|
def create_cgsnapshot_member(cgsnapshot_id, **kwargs):
|
|
"""Create a cgsnapshot member object."""
|
|
member = {
|
|
'share_proto': "NFS",
|
|
'size': 0,
|
|
'share_id': None,
|
|
'share_instance_id': None,
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'status': 'creating',
|
|
'cgsnapshot_id': cgsnapshot_id,
|
|
}
|
|
return _create_db_row(db.cgsnapshot_member_create, member, kwargs)
|
|
|
|
|
|
def create_share(**kwargs):
|
|
"""Create a share object."""
|
|
share = {
|
|
'share_proto': "NFS",
|
|
'size': 0,
|
|
'snapshot_id': None,
|
|
'share_network_id': None,
|
|
'share_server_id': None,
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'metadata': {'fake_key': 'fake_value'},
|
|
'availability_zone': 'fake_availability_zone',
|
|
'status': constants.STATUS_CREATING,
|
|
'host': 'fake_host'
|
|
}
|
|
return _create_db_row(db.share_create, share, kwargs)
|
|
|
|
|
|
def create_share_instance(**kwargs):
|
|
"""Create a share instance object."""
|
|
instance = {
|
|
'host': 'fake',
|
|
'status': constants.STATUS_CREATING,
|
|
}
|
|
instance.update(kwargs)
|
|
|
|
return db.share_instance_create(context.get_admin_context(),
|
|
kwargs.pop('share_id'), kwargs)
|
|
|
|
|
|
def create_share_replica(**kwargs):
|
|
"""Create a share replica object."""
|
|
replica = {
|
|
'host': 'fake',
|
|
'status': constants.STATUS_CREATING,
|
|
}
|
|
replica.update(kwargs)
|
|
|
|
return db.share_instance_create(context.get_admin_context(),
|
|
kwargs.pop('share_id'), kwargs)
|
|
|
|
|
|
def create_snapshot(**kwargs):
|
|
"""Create a snapshot object."""
|
|
with_share = kwargs.pop('with_share', False)
|
|
|
|
share = None
|
|
if with_share:
|
|
share = create_share(status=constants.STATUS_AVAILABLE,
|
|
size=kwargs.get('size', 0))
|
|
|
|
snapshot = {
|
|
'share_proto': "NFS",
|
|
'size': 0,
|
|
'share_id': share['id'] if with_share else None,
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'status': 'creating'
|
|
}
|
|
return _create_db_row(db.share_snapshot_create, snapshot, kwargs)
|
|
|
|
|
|
def create_access(**kwargs):
|
|
"""Create a access rule object."""
|
|
access = {
|
|
'access_type': 'fake_type',
|
|
'access_to': 'fake_IP',
|
|
'share_id': None,
|
|
}
|
|
return _create_db_row(db.share_access_create, access, kwargs)
|
|
|
|
|
|
def create_share_server(**kwargs):
|
|
"""Create a share server object."""
|
|
backend_details = kwargs.pop('backend_details', {})
|
|
srv = {
|
|
'host': 'host1',
|
|
'share_network_id': 'fake_srv_id',
|
|
'status': constants.STATUS_ACTIVE
|
|
}
|
|
share_srv = _create_db_row(db.share_server_create, srv, kwargs)
|
|
if backend_details:
|
|
db.share_server_backend_details_set(
|
|
context.get_admin_context(), share_srv['id'], backend_details)
|
|
return db.share_server_get(context.get_admin_context(),
|
|
share_srv['id'])
|
|
|
|
|
|
def create_share_network(**kwargs):
|
|
"""Create a share network object."""
|
|
net = {
|
|
'user_id': 'fake',
|
|
'project_id': 'fake',
|
|
'neutron_net_id': 'fake-neutron-net',
|
|
'neutron_subnet_id': 'fake-neutron-subnet',
|
|
'status': 'new',
|
|
'network_type': 'vlan',
|
|
'segmentation_id': 1000,
|
|
'cidr': '10.0.0.0/24',
|
|
'ip_version': 4,
|
|
'name': 'whatever',
|
|
'description': 'fake description',
|
|
}
|
|
return _create_db_row(db.share_network_create, net, kwargs)
|
|
|
|
|
|
def create_security_service(**kwargs):
|
|
share_network_id = kwargs.pop('share_network_id', None)
|
|
service = {
|
|
'type': "FAKE",
|
|
'project_id': 'fake-project-id',
|
|
}
|
|
service_ref = _create_db_row(db.security_service_create, service, kwargs)
|
|
|
|
if share_network_id:
|
|
db.share_network_add_security_service(context.get_admin_context(),
|
|
share_network_id,
|
|
service_ref['id'])
|
|
return service_ref
|