Adds v2 replication support
v2 replication has been merged in cinder, but there is no way to call the api methods. This patch allows the following methods to be called in order to fully support v2 replication: - os-enable_replication - os-disable_replication - os-list_replication_targets - os-failover_replication Change-Id: Ic3cf082916bdf089de05eebce456dff8cdc11f7c Implements: blueprint replication-v2
This commit is contained in:
@@ -437,6 +437,14 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
elif action == 'os-migrate_volume':
|
||||
assert 'host' in body[action]
|
||||
assert 'force_host_copy' in body[action]
|
||||
elif action == 'os-enable_replication':
|
||||
assert body[action] is None
|
||||
elif action == 'os-disable_replication':
|
||||
assert body[action] is None
|
||||
elif action == 'os-list_replication_targets':
|
||||
assert body[action] is None
|
||||
elif action == 'os-failover_replication':
|
||||
assert 'secondary' in body[action]
|
||||
elif action == 'os-update_readonly_flag':
|
||||
assert list(body[action]) == ['readonly']
|
||||
elif action == 'os-retype':
|
||||
|
||||
@@ -772,6 +772,23 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('POST', '/volumes/1234/action',
|
||||
body=expected)
|
||||
|
||||
def test_replication_enable(self):
|
||||
self.run_command('replication-enable 1234')
|
||||
self.assert_called('POST', '/volumes/1234/action')
|
||||
|
||||
def test_replication_disable(self):
|
||||
self.run_command('replication-disable 1234')
|
||||
self.assert_called('POST', '/volumes/1234/action')
|
||||
|
||||
def test_replication_list_targets(self):
|
||||
self.run_command('replication-list-targets 1234')
|
||||
self.assert_called('POST', '/volumes/1234/action')
|
||||
|
||||
def test_replication_failover(self):
|
||||
self.run_command('replication-failover 1234 target')
|
||||
expected = {'os-failover_replication': {'secondary': 'target'}}
|
||||
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||
|
||||
def test_snapshot_metadata_set(self):
|
||||
self.run_command('snapshot-metadata 1234 set key1=val1 key2=val2')
|
||||
self.assert_called('POST', '/snapshots/1234/metadata',
|
||||
|
||||
@@ -1206,6 +1206,60 @@ def do_migrate(cs, args):
|
||||
six.text_type(e)))
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='ID of volume to enable replication.')
|
||||
@utils.service_type('volumev2')
|
||||
def do_replication_enable(cs, args):
|
||||
"""Enables volume replication on a given volume."""
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
volume.replication_enable(args.volume)
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='ID of volume to disable replication.')
|
||||
@utils.service_type('volumev2')
|
||||
def do_replication_disable(cs, args):
|
||||
"""Disables volume replication on a given volume."""
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
volume.replication_disable(args.volume)
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='ID of volume to list available replication targets.')
|
||||
@utils.service_type('volumev2')
|
||||
def do_replication_list_targets(cs, args):
|
||||
"""List replication targets available for a volume."""
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
resp, body = volume.replication_list_targets(args.volume)
|
||||
if body:
|
||||
targets = body['targets']
|
||||
columns = ['target_device_id']
|
||||
if targets:
|
||||
utils.print_list(targets, columns)
|
||||
else:
|
||||
print("There are no replication targets found for volume %s." %
|
||||
args.volume)
|
||||
else:
|
||||
print("There is no replication information for volume %s." %
|
||||
args.volume)
|
||||
|
||||
|
||||
@utils.arg('volume',
|
||||
metavar='<volume>',
|
||||
help='ID of volume to failover.')
|
||||
@utils.arg('secondary',
|
||||
metavar='<secondary>',
|
||||
help='A unqiue identifier that represents a failover target.')
|
||||
@utils.service_type('volumev2')
|
||||
def do_replication_failover(cs, args):
|
||||
"""Failover a volume to a secondary target"""
|
||||
volume = utils.find_volume(cs, args.volume)
|
||||
volume.replication_failover(args.volume, args.secondary)
|
||||
|
||||
|
||||
@utils.arg('volume', metavar='<volume>',
|
||||
help='Name or ID of volume for which to modify type.')
|
||||
@utils.arg('new_type', metavar='<volume-type>', help='New volume type.')
|
||||
|
||||
@@ -150,6 +150,22 @@ class Volume(base.Resource):
|
||||
"""Migrate the volume to a new host."""
|
||||
self.manager.migrate_volume(self, host, force_host_copy, lock_volume)
|
||||
|
||||
def replication_enable(self, volume):
|
||||
"""Enables volume replication on a given volume."""
|
||||
return self.manager.replication_enable(volume)
|
||||
|
||||
def replication_disable(self, volume):
|
||||
"""Disables volume replication on a given volume."""
|
||||
return self.manager.replication_disable(volume)
|
||||
|
||||
def replication_list_targets(self, volume):
|
||||
"""List replication targets available for a volume."""
|
||||
return self.manager.replication_list_targets(volume)
|
||||
|
||||
def replication_failover(self, volume, secondary):
|
||||
"""Failover a volume to a secondary target."""
|
||||
return self.manager.replication_failover(volume, secondary)
|
||||
|
||||
def retype(self, volume_type, policy):
|
||||
"""Change a volume's type."""
|
||||
self.manager.retype(self, volume_type, policy)
|
||||
@@ -601,6 +617,46 @@ class VolumeManager(base.ManagerWithFind):
|
||||
old_volume,
|
||||
{'new_volume': new_volume_id, 'error': error})[1]
|
||||
|
||||
def replication_enable(self, volume_id):
|
||||
"""
|
||||
Enables volume replication on a given volume.
|
||||
|
||||
:param volume_id: The id of the volume to query
|
||||
"""
|
||||
return self._action('os-enable_replication',
|
||||
volume_id)
|
||||
|
||||
def replication_disable(self, volume_id):
|
||||
"""
|
||||
Disables volume replication on a given volume.
|
||||
|
||||
:param volume_id: The id of the volume to query
|
||||
"""
|
||||
return self._action('os-disable_replication',
|
||||
volume_id)
|
||||
|
||||
def replication_list_targets(self, volume_id):
|
||||
"""
|
||||
List replication targets available for a volume.
|
||||
|
||||
:param volume_id: The id of the volume to query
|
||||
:return: a list of available replication targets
|
||||
"""
|
||||
return self._action('os-list_replication_targets',
|
||||
volume_id)
|
||||
|
||||
def replication_failover(self, volume_id, secondary):
|
||||
"""
|
||||
Failover a volume to a secondary target.
|
||||
|
||||
:param volume_id: The id of the volume to query
|
||||
:param secondary: A unqiue identifier that represents a failover
|
||||
target
|
||||
"""
|
||||
return self._action('os-failover_replication',
|
||||
volume_id,
|
||||
{"secondary": secondary})
|
||||
|
||||
def update_all_metadata(self, volume, metadata):
|
||||
"""Update all metadata of a volume.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user