Handle ServicechainSpec update for all ServiceChain instances
Change-Id: I82b6662914e9e29749b3a063efd5214fcfc9e7f0 Closes-bug: #1387440
This commit is contained in:
@@ -82,13 +82,14 @@ class SimpleChainDriver(object):
|
||||
|
||||
@log.log
|
||||
def update_servicechain_spec_postcommit(self, context):
|
||||
filters = {'servicechain_spec': [context.original['id']]}
|
||||
sc_instances = context._plugin.get_servicechain_instances(
|
||||
context._plugin_context, filters)
|
||||
if sc_instances:
|
||||
self._update_servicechain_instance(context,
|
||||
sc_instances[0],
|
||||
context._sc_spec)
|
||||
if context.original['nodes'] != context.current['nodes']:
|
||||
filters = {'servicechain_spec': [context.original['id']]}
|
||||
sc_instances = context._plugin.get_servicechain_instances(
|
||||
context._plugin_context, filters)
|
||||
for sc_instance in sc_instances:
|
||||
self._update_servicechain_instance(context,
|
||||
sc_instance,
|
||||
context._sc_spec)
|
||||
|
||||
@log.log
|
||||
def delete_servicechain_spec_precommit(self, context):
|
||||
@@ -249,12 +250,13 @@ class SimpleChainDriver(object):
|
||||
context._plugin_context, filters)
|
||||
|
||||
def _update_servicechain_instance(self, context, sc_instance, newspec):
|
||||
self._delete_servicechain_instance_stacks(context._plugin_context,
|
||||
sc_instance['id'])
|
||||
sc_node_ids = newspec.get('nodes')
|
||||
self._create_servicechain_instance_stacks(context,
|
||||
sc_node_ids,
|
||||
sc_instance)
|
||||
self._delete_servicechain_instance_stacks(context._plugin_context,
|
||||
sc_instance['id'])
|
||||
sc_node_ids = newspec.get('nodes')
|
||||
self._create_servicechain_instance_stacks(context,
|
||||
sc_node_ids,
|
||||
sc_instance,
|
||||
newspec)
|
||||
|
||||
def _delete_chain_stacks_db(self, session, sc_instance_id):
|
||||
with session.begin(subtransactions=True):
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
from neutron.openstack.common import jsonutils
|
||||
from neutron.openstack.common import uuidutils
|
||||
import webob
|
||||
|
||||
@@ -34,6 +36,75 @@ class SimpleChainDriverTestCase(
|
||||
|
||||
class TestServiceChainInstance(SimpleChainDriverTestCase):
|
||||
|
||||
def test_chain_spec_update(self):
|
||||
template1 = '{"key1":"value1"}'
|
||||
scn = self.create_servicechain_node(config=template1)
|
||||
scn1_name = scn['servicechain_node']['name']
|
||||
scn_id = scn['servicechain_node']['id']
|
||||
name = "scs1"
|
||||
template2 = '{"key2":"value2"}'
|
||||
scn2 = self.create_servicechain_node(config=template2)
|
||||
scn2_id = scn2['servicechain_node']['id']
|
||||
scn2_name = scn2['servicechain_node']['name']
|
||||
scs = self.create_servicechain_spec(name=name, nodes=[scn_id])
|
||||
sc_spec_id = scs['servicechain_spec']['id']
|
||||
|
||||
stack1 = {'stack': {'id': uuidutils.generate_uuid()}}
|
||||
stack2 = {'stack': {'id': uuidutils.generate_uuid()}}
|
||||
stack3 = {'stack': {'id': uuidutils.generate_uuid()}}
|
||||
expected_create_calls = []
|
||||
expected_delete_calls = []
|
||||
with contextlib.nested(
|
||||
mock.patch.object(simplechain_driver.HeatClient,
|
||||
'create'),
|
||||
mock.patch.object(simplechain_driver.HeatClient,
|
||||
'delete'),
|
||||
) as (stack_create, stack_delete):
|
||||
stack_create.return_value = stack1
|
||||
instance1_name = "sc_instance_1"
|
||||
sc_instance1 = self.create_servicechain_instance(
|
||||
name=instance1_name,
|
||||
servicechain_spec=sc_spec_id)
|
||||
self.assertEqual(
|
||||
sc_instance1['servicechain_instance']['servicechain_spec'],
|
||||
sc_spec_id)
|
||||
stack_name = "stack_" + instance1_name + scn1_name + scn_id[:5]
|
||||
expected_create_calls.append(
|
||||
mock.call(stack_name, jsonutils.loads(template1), {}))
|
||||
stack_create.return_value = stack2
|
||||
instance2_name = "sc_instance_2"
|
||||
sc_instance2 = self.create_servicechain_instance(
|
||||
name=instance2_name,
|
||||
servicechain_spec=sc_spec_id)
|
||||
self.assertEqual(
|
||||
sc_instance2['servicechain_instance']['servicechain_spec'],
|
||||
sc_spec_id)
|
||||
stack_name = "stack_" + instance2_name + scn1_name + scn_id[:5]
|
||||
expected_create_calls.append(
|
||||
mock.call(stack_name, jsonutils.loads(template1), {}))
|
||||
|
||||
#Now perform an update of the spec
|
||||
new_spec = {'servicechain_spec': {'nodes': [scn2_id]}}
|
||||
stack_create.return_value = stack3
|
||||
req = self.new_update_request(
|
||||
'servicechain_specs', new_spec, sc_spec_id)
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, webob.exc.HTTPOk.code)
|
||||
# The two existing stacks will be deleted and two new stacks
|
||||
# will be created
|
||||
expected_delete_calls.append(mock.call(stack1['stack']['id']))
|
||||
expected_delete_calls.append(mock.call(stack2['stack']['id']))
|
||||
stack_name = "stack_" + instance1_name + scn2_name + scn2_id[:5]
|
||||
expected_create_calls.append(
|
||||
mock.call(stack_name, jsonutils.loads(template2), {}))
|
||||
stack_name = "stack_" + instance2_name + scn2_name + scn2_id[:5]
|
||||
expected_create_calls.append(
|
||||
mock.call(stack_name, jsonutils.loads(template2), {}))
|
||||
self.assertEqual(expected_delete_calls,
|
||||
stack_delete.call_args_list)
|
||||
self.assertEqual(expected_create_calls,
|
||||
stack_create.call_args_list)
|
||||
|
||||
def test_chain_instance_create(self):
|
||||
name = "scs1"
|
||||
scn = self.create_servicechain_node()
|
||||
|
||||
Reference in New Issue
Block a user