NetApp SolidFire: Add options for replication mode
This adds the option to specify the replication mode as: Synchronous, Asynchronous or SnapshotOnly. Depends-On: I920f958db1d48e52b548082d852c03f427a279ca Change-Id: I74d31e7a262f3a59f5e82c710f3ca5fd84e3ea60
This commit is contained in:
parent
33b32d9820
commit
ddc91052e4
@ -18,7 +18,10 @@ import datetime
|
||||
import re
|
||||
import six
|
||||
|
||||
import ddt
|
||||
from ddt import data
|
||||
from ddt import ddt
|
||||
from ddt import file_data
|
||||
from ddt import unpack
|
||||
import mock
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import units
|
||||
@ -63,7 +66,7 @@ f_uuid = ['262b9ce2-a71a-4fbe-830c-c20c5596caea',
|
||||
'362b9ce2-a71a-4fbe-830c-c20c5596caea']
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@ddt
|
||||
class SolidFireVolumeTestCase(test.TestCase):
|
||||
|
||||
EXPECTED_QOS = {'minIOPS': 110, 'burstIOPS': 1530, 'maxIOPS': 1020}
|
||||
@ -1237,8 +1240,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
qos = sfv._set_qos_by_volume_type(self.ctxt, type_ref['id'], size)
|
||||
self.assertEqual(self.expected_qos_results, qos)
|
||||
|
||||
@ddt.file_data("scaled_iops_test_data.json")
|
||||
@ddt.unpack
|
||||
@file_data("scaled_iops_test_data.json")
|
||||
@unpack
|
||||
def test_scaled_qos_spec_by_type(self, argument):
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
size = argument[0].pop('size')
|
||||
@ -1246,8 +1249,8 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
qos = sfv._set_qos_by_volume_type(self.ctxt, type_ref['id'], size)
|
||||
self.assertEqual(argument[1], qos)
|
||||
|
||||
@ddt.file_data("scaled_iops_invalid_data.json")
|
||||
@ddt.unpack
|
||||
@file_data("scaled_iops_invalid_data.json")
|
||||
@unpack
|
||||
def test_set_scaled_qos_by_type_invalid(self, inputs):
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
size = inputs[0].pop('size')
|
||||
@ -2684,22 +2687,31 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def test_set_rep_by_volume_type(self):
|
||||
@data('Async', 'Sync', 'SnapshotsOnly')
|
||||
@mock.patch.object(volume_types, 'get_volume_type')
|
||||
def test_set_rep_by_volume_type(self, mode, mock_get_volume_type):
|
||||
mock_get_volume_type.return_value = {
|
||||
'name': 'sf-1', 'deleted': False,
|
||||
'created_at': '2014-02-06 04:58:11',
|
||||
'updated_at': None, 'extra_specs':
|
||||
{'replication_enabled': '<is> True',
|
||||
'solidfire:replication_mode': mode},
|
||||
'deleted_at': None,
|
||||
'id': '290edb2a-f5ea-11e5-9ce9-5e5517507c66'}
|
||||
rep_opts = {}
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
sfv.cluster_pairs = self.cluster_pairs
|
||||
ctxt = None
|
||||
type_id = '290edb2a-f5ea-11e5-9ce9-5e5517507c66'
|
||||
fake_type = {'extra_specs': {'replication_enabled': '<is> True'}}
|
||||
with mock.patch.object(volume_types,
|
||||
'get_volume_type',
|
||||
return_value=fake_type):
|
||||
self.assertEqual('Async', sfv._set_rep_by_volume_type(
|
||||
ctxt, type_id))
|
||||
rep_opts['rep_type'] = mode
|
||||
self.assertEqual(rep_opts, sfv._set_rep_by_volume_type(ctxt, type_id))
|
||||
mock_get_volume_type.assert_called()
|
||||
|
||||
def test_replicate_volume(self):
|
||||
replication_status = fields.ReplicationStatus.ENABLED
|
||||
fake_vol = {'project_id': 1, 'volumeID': 1, 'size': 1}
|
||||
params = {'attributes': {}}
|
||||
rep_info = {'rep_type': 'Async'}
|
||||
sf_account = {'initiatorSecret': 'shhh', 'targetSecret': 'dont-tell'}
|
||||
model_update = {'provider_id': '1 2 xxxx'}
|
||||
sfv = solidfire.SolidFireDriver(configuration=self.configuration)
|
||||
@ -2716,7 +2728,7 @@ class SolidFireVolumeTestCase(test.TestCase):
|
||||
return_value=model_update):
|
||||
self.assertEqual({'replication_status': replication_status},
|
||||
sfv._replicate_volume(fake_vol, params,
|
||||
sf_account, {}))
|
||||
sf_account, rep_info))
|
||||
|
||||
def test_pythons_try_except(self):
|
||||
def _fake_retrieve_rep(vol):
|
||||
|
@ -221,9 +221,11 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
2.0.12 - Fix bug #1744005
|
||||
2.0.14 - Fix bug #1782588 qos settings on extend
|
||||
2.0.15 - Fix bug #1834013 NetApp SolidFire replication errors
|
||||
2.0.16 - Add options for replication mode (Async, Sync and
|
||||
SnapshotsOnly)
|
||||
"""
|
||||
|
||||
VERSION = '2.0.15'
|
||||
VERSION = '2.0.16'
|
||||
|
||||
# ThirdPartySystems wiki page
|
||||
CI_WIKI_NAME = "NetApp_SolidFire_CI"
|
||||
@ -323,6 +325,18 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
def get_driver_options():
|
||||
return sf_opts
|
||||
|
||||
def _init_vendor_properties(self):
|
||||
properties = {}
|
||||
self._set_property(
|
||||
properties,
|
||||
"solidfire:replication_mode",
|
||||
"Replication mode",
|
||||
_("Specifies replication mode."),
|
||||
"string",
|
||||
enum=["Async", "Sync", "SnapshotsOnly"])
|
||||
|
||||
return properties, 'solidfire'
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if hasattr(self.target_driver, attr):
|
||||
return getattr(self.target_driver, attr)
|
||||
@ -1412,15 +1426,17 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
return rep_data
|
||||
|
||||
def _set_rep_by_volume_type(self, ctxt, type_id):
|
||||
rep_type = None
|
||||
rep_modes = ['Async', 'Sync', 'SnapshotsOnly']
|
||||
rep_opts = {}
|
||||
type_ref = volume_types.get_volume_type(ctxt, type_id)
|
||||
specs = type_ref.get('extra_specs')
|
||||
|
||||
# TODO(erlon): Add support for sync/snapshot replication
|
||||
if specs.get('replication_enabled', "") == "<is> True":
|
||||
rep_type = 'Async'
|
||||
if specs.get('solidfire:replication_mode') in rep_modes:
|
||||
rep_opts['rep_type'] = specs.get('solidfire:replication_mode')
|
||||
else:
|
||||
rep_opts['rep_type'] = 'Async'
|
||||
|
||||
return rep_type
|
||||
return rep_opts
|
||||
|
||||
def _replicate_volume(self, volume, params,
|
||||
parent_sfaccount, rep_info):
|
||||
@ -1476,7 +1492,8 @@ class SolidFireDriver(san.SanISCSIDriver):
|
||||
volume['volumeID'])
|
||||
|
||||
# Make sure we split any pair the volume have
|
||||
params = {'volumeID': volume['volumeID'], 'mode': rep_info}
|
||||
params = {'volumeID': volume['volumeID'],
|
||||
'mode': rep_info['rep_type']}
|
||||
self._issue_api_request('RemoveVolumePair', params, '8.0')
|
||||
|
||||
rep_key = self._issue_api_request(
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
SolidFire supports Synchronous, Asynchronous and SnapshotsOnly replication
|
||||
modes. This adds the config option `solidfire:replication_mode` to specify
|
||||
the mode to be used by Cinder. Its value can be `Sync`, `Async` or
|
||||
`SnapshotsOnly`.
|
Loading…
Reference in New Issue
Block a user