Merge "volume: Add volume group replication actions"
This commit is contained in:
commit
d246545a9d
@ -1625,26 +1625,6 @@ class Proxy(proxy.Proxy):
|
||||
"""
|
||||
return _group.Group.create_from_source(self, **attrs)
|
||||
|
||||
def reset_group_status(self, group, status):
|
||||
"""Reset group status
|
||||
|
||||
:param group: The :class:`~openstack.block_storage.v3.group.Group`
|
||||
to set the state.
|
||||
:param status: The status for a group.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
res = self._get_resource(_group.Group, group)
|
||||
return res.reset_status(self, status)
|
||||
|
||||
def reset_group_state(self, group, status):
|
||||
warnings.warn(
|
||||
"reset_group_state is a deprecated alias for reset_group_status "
|
||||
"and will be removed in a future release.",
|
||||
os_warnings.RemovedInSDK60Warning,
|
||||
)
|
||||
return self.reset_group_status(group, status)
|
||||
|
||||
def delete_group(self, group, delete_volumes=False):
|
||||
"""Delete a group
|
||||
|
||||
@ -1670,6 +1650,72 @@ class Proxy(proxy.Proxy):
|
||||
"""
|
||||
return self._update(_group.Group, group, **attrs)
|
||||
|
||||
def reset_group_status(self, group, status):
|
||||
"""Reset group status
|
||||
|
||||
:param group: The :class:`~openstack.block_storage.v3.group.Group`
|
||||
to set the state.
|
||||
:param status: The status for a group.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
res = self._get_resource(_group.Group, group)
|
||||
return res.reset_status(self, status)
|
||||
|
||||
def reset_group_state(self, group, status):
|
||||
warnings.warn(
|
||||
"reset_group_state is a deprecated alias for reset_group_status "
|
||||
"and will be removed in a future release.",
|
||||
os_warnings.RemovedInSDK60Warning,
|
||||
)
|
||||
return self.reset_group_status(group, status)
|
||||
|
||||
def enable_group_replication(self, group):
|
||||
"""Enable replication for a group
|
||||
|
||||
:param group: The :class:`~openstack.block_storage.v3.group.Group`
|
||||
to enable replication for.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
res = self._get_resource(_group.Group, group)
|
||||
return res.enable_replication(self)
|
||||
|
||||
def disable_group_replication(self, group):
|
||||
"""Disable replication for a group
|
||||
|
||||
:param group: The :class:`~openstack.block_storage.v3.group.Group`
|
||||
to disable replication for.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
res = self._get_resource(_group.Group, group)
|
||||
return res.disable_replication(self)
|
||||
|
||||
def failover_group_replication(
|
||||
self,
|
||||
group,
|
||||
*,
|
||||
allowed_attached_volume=False,
|
||||
secondary_backend_id=None,
|
||||
):
|
||||
"""Failover replication for a group
|
||||
|
||||
:param group: The :class:`~openstack.block_storage.v3.group.Group`
|
||||
to failover replication for.
|
||||
:param allowed_attached_volume: Whether to allow attached volumes in
|
||||
the group.
|
||||
:param secondary_backend_id: The secondary backend ID.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
res = self._get_resource(_group.Group, group)
|
||||
return res.failover_replication(
|
||||
self,
|
||||
allowed_attached_volume=allowed_attached_volume,
|
||||
secondary_backend_id=secondary_backend_id,
|
||||
)
|
||||
|
||||
# ====== AVAILABILITY ZONES ======
|
||||
def availability_zones(self):
|
||||
"""Return a generator of availability zones
|
||||
|
@ -46,6 +46,7 @@ class Group(resource.Resource):
|
||||
group_snapshot_id = resource.Body("group_snapshot_id")
|
||||
group_type = resource.Body("group_type")
|
||||
project_id = resource.Body("project_id")
|
||||
replication_targets = resource.Body("replication_targets", type=list)
|
||||
replication_status = resource.Body("replication_status")
|
||||
source_group_id = resource.Body("source_group_id")
|
||||
status = resource.Body("status")
|
||||
@ -68,8 +69,64 @@ class Group(resource.Resource):
|
||||
body = {'delete': {'delete-volumes': delete_volumes}}
|
||||
self._action(session, body)
|
||||
|
||||
def fetch_replication_targets(self, session):
|
||||
"""Fetch replication targets for the group.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:return: This group with the ``replication_targets`` field populated.
|
||||
"""
|
||||
body = {'list_replication_targets': None}
|
||||
response = self._action(session, body)
|
||||
self._body.attributes.update(
|
||||
{'replication_targets': response.json()['replication_targets']}
|
||||
)
|
||||
return self
|
||||
|
||||
def enable_replication(self, session):
|
||||
"""Enable replication for the group.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
"""
|
||||
body = {'enable_replication': None}
|
||||
self._action(session, body)
|
||||
|
||||
def disable_replication(self, session):
|
||||
"""Disable replication for the group.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
"""
|
||||
body = {'disable_replication': None}
|
||||
self._action(session, body)
|
||||
|
||||
def failover_replication(
|
||||
self,
|
||||
session,
|
||||
*,
|
||||
allowed_attached_volume=False,
|
||||
secondary_backend_id=None,
|
||||
):
|
||||
"""Failover replication for the group.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:param allowed_attached_volume: Whether to allow attached volumes in
|
||||
the group.
|
||||
:param secondary_backend_id: The secondary backend ID.
|
||||
:returns: None
|
||||
"""
|
||||
body = {
|
||||
'modify_body_for_action': {
|
||||
'allow_attached_volume': allowed_attached_volume,
|
||||
'secondary_backend_id': secondary_backend_id,
|
||||
},
|
||||
}
|
||||
self._action(session, body)
|
||||
|
||||
def reset_status(self, session, status):
|
||||
"""Resets the status for a group."""
|
||||
"""Resets the status for a group.
|
||||
|
||||
:param session: The session to use for making this request.
|
||||
:param status: The status for the group.
|
||||
"""
|
||||
body = {'reset_status': {'status': status}}
|
||||
self._action(session, body)
|
||||
|
||||
|
@ -93,6 +93,85 @@ class TestGroupAction(base.TestCase):
|
||||
url, json=body, microversion=sot._max_microversion
|
||||
)
|
||||
|
||||
def test_enable_replication(self):
|
||||
sot = group.Group(**GROUP)
|
||||
|
||||
ret = sot.enable_replication(self.sess)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
url = f'groups/{GROUP_ID}/action'
|
||||
body = {'enable_replication': None}
|
||||
self.sess.post.assert_called_with(
|
||||
url,
|
||||
json=body,
|
||||
microversion=sot._max_microversion,
|
||||
)
|
||||
|
||||
def test_disable_replication(self):
|
||||
sot = group.Group(**GROUP)
|
||||
|
||||
ret = sot.disable_replication(self.sess)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
url = f'groups/{GROUP_ID}/action'
|
||||
body = {'disable_replication': None}
|
||||
self.sess.post.assert_called_with(
|
||||
url,
|
||||
json=body,
|
||||
microversion=sot._max_microversion,
|
||||
)
|
||||
|
||||
def test_failover_replication(self):
|
||||
sot = group.Group(**GROUP)
|
||||
|
||||
ret = sot.failover_replication(
|
||||
self.sess, allowed_attached_volume=True, secondary_backend_id=None
|
||||
)
|
||||
self.assertIsNone(ret)
|
||||
|
||||
url = f'groups/{GROUP_ID}/action'
|
||||
body = {
|
||||
'modify_body_for_action': {
|
||||
'allow_attached_volume': True,
|
||||
'secondary_backend_id': None,
|
||||
}
|
||||
}
|
||||
self.sess.post.assert_called_with(
|
||||
url,
|
||||
json=body,
|
||||
microversion=sot._max_microversion,
|
||||
)
|
||||
|
||||
def test_fetch_replication_targets(self):
|
||||
resp = mock.Mock()
|
||||
resp.links = {}
|
||||
resp.json = mock.Mock(
|
||||
return_value={
|
||||
'replication_targets': [
|
||||
{
|
||||
'backend_id': 'vendor-id-1',
|
||||
'unique_key': 'val1',
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
resp.status_code = 200
|
||||
|
||||
self.sess.post = mock.Mock(return_value=resp)
|
||||
|
||||
sot = group.Group(**GROUP)
|
||||
result = sot.fetch_replication_targets(self.sess)
|
||||
self.assertEqual(
|
||||
[
|
||||
{
|
||||
'backend_id': 'vendor-id-1',
|
||||
'unique_key': 'val1',
|
||||
},
|
||||
],
|
||||
sot.replication_targets,
|
||||
)
|
||||
self.assertEqual(sot, result)
|
||||
|
||||
def test_reset_status(self):
|
||||
sot = group.Group(**GROUP)
|
||||
|
||||
|
@ -237,7 +237,7 @@ class TestGroup(TestVolumeProxy):
|
||||
def test_group_update(self):
|
||||
self.verify_update(self.proxy.update_group, group.Group)
|
||||
|
||||
def test_reset_group_status(self):
|
||||
def test_group_reset_status(self):
|
||||
self._verify(
|
||||
"openstack.block_storage.v3.group.Group.reset_status",
|
||||
self.proxy.reset_group_status,
|
||||
@ -245,6 +245,34 @@ class TestGroup(TestVolumeProxy):
|
||||
expected_args=[self.proxy, "new_status"],
|
||||
)
|
||||
|
||||
def test_group_enable_replication(self):
|
||||
self._verify(
|
||||
"openstack.block_storage.v3.group.Group.enable_replication",
|
||||
self.proxy.enable_group_replication,
|
||||
method_args=["value"],
|
||||
expected_args=[self.proxy],
|
||||
)
|
||||
|
||||
def test_group_disable_replication(self):
|
||||
self._verify(
|
||||
"openstack.block_storage.v3.group.Group.disable_replication",
|
||||
self.proxy.disable_group_replication,
|
||||
method_args=["value"],
|
||||
expected_args=[self.proxy],
|
||||
)
|
||||
|
||||
def test_group_failover_replication(self):
|
||||
self._verify(
|
||||
"openstack.block_storage.v3.group.Group.failover_replication",
|
||||
self.proxy.failover_group_replication,
|
||||
method_args=["value"],
|
||||
expected_args=[self.proxy],
|
||||
expected_kwargs={
|
||||
'allowed_attached_volume': False,
|
||||
'secondary_backend_id': None,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class TestGroupSnapshot(TestVolumeProxy):
|
||||
def test_group_snapshot_get(self):
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for the volume group replication actions.
|
Loading…
x
Reference in New Issue
Block a user