NFP changes to support async model
Following are the NFP side changes to support async operations. 1. Added get_status api in nfp_node_driver to update operational state of servicechain node. 2. Using queue notifications to send rpc to orchestrator. 3. Extended ncp_node_instance_network_function_mappings table to have status and status_details of an network_function. Change-Id: I5375066fb640d53c6bc5f0a7cf65902faa221519 Co-Authored-By: Ashutosh Mishra <mca.ashu4@gmail.com> Closes-Bug: 1671077
This commit is contained in:
parent
283a53b4e8
commit
dc25f71543
@ -1 +1 @@
|
||||
cb5b16acbeb0
|
||||
bff1774e749e
|
||||
|
@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
"""ncp_sci_nf_status
|
||||
|
||||
Revision ID: bff1774e749e
|
||||
Revises: cb5b16acbeb0
|
||||
Create Date: 2017-02-24 00:16:12.276236
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'bff1774e749e'
|
||||
down_revision = 'cb5b16acbeb0'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_constraint('PRIMARY',
|
||||
'ncp_node_instance_network_function_mappings',
|
||||
type_='primary')
|
||||
op.create_primary_key("ncp_node_instance_network_function_mappings_pk",
|
||||
"ncp_node_instance_network_function_mappings",
|
||||
['sc_instance_id', 'sc_node_id'])
|
||||
op.alter_column('ncp_node_instance_network_function_mappings',
|
||||
'network_function_id',
|
||||
nullable=True, existing_type=sa.String(length=36))
|
||||
op.add_column('ncp_node_instance_network_function_mappings',
|
||||
sa.Column('status', sa.String(length=50), nullable=True))
|
||||
op.add_column('ncp_node_instance_network_function_mappings',
|
||||
sa.Column('status_details', sa.String(length=4096),
|
||||
nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
@ -1575,6 +1575,9 @@ class ResourceMappingDriver(api.PolicyDriver, ImplicitResourceOperations,
|
||||
self._update_cluster_membership(
|
||||
context, new_cluster_id=context.current['cluster_id'],
|
||||
old_cluster_id=context.original['cluster_id'])
|
||||
if not context.current.get('port_id') and context.current.get(
|
||||
'proxy_gateway'):
|
||||
self._unset_proxy_gateway_routes(context, context.original)
|
||||
|
||||
@log.log_method_call
|
||||
def delete_policy_target_precommit(self, context):
|
||||
|
@ -29,12 +29,13 @@ import oslo_messaging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import excutils
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
from gbpservice._i18n import _
|
||||
from gbpservice._i18n import _LE
|
||||
from gbpservice._i18n import _LI
|
||||
from gbpservice._i18n import _LW
|
||||
from gbpservice.common import utils
|
||||
from gbpservice.network.neutronv2 import local_api
|
||||
from gbpservice.neutron.services.grouppolicy.common import constants as gconst
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import (
|
||||
exceptions as exc)
|
||||
@ -44,6 +45,7 @@ from gbpservice.neutron.services.servicechain.plugins.ncp import driver_base
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import plumber_base
|
||||
from gbpservice.nfp.common import constants as nfp_constants
|
||||
from gbpservice.nfp.common import topics as nfp_rpc_topics
|
||||
from gbpservice.nfp.orchestrator.db import nfp_db as nfp_db
|
||||
|
||||
|
||||
NFP_NODE_DRIVER_OPTS = [
|
||||
@ -69,6 +71,7 @@ LOG = logging.getLogger(__name__)
|
||||
# REVISIT: L2 insertion not supported
|
||||
GATEWAY_PLUMBER_TYPE = [pconst.FIREWALL, pconst.VPN]
|
||||
nfp_context_store = threading.local()
|
||||
local_api.BATCH_NOTIFICATIONS = True
|
||||
|
||||
|
||||
class InvalidServiceType(exc.NodeCompositionPluginBadRequest):
|
||||
@ -133,6 +136,11 @@ class NodeInstanceUpdateFailed(n_exc.NeutronException):
|
||||
message = _("Node instance update failed in NFP Node driver")
|
||||
|
||||
|
||||
class OperationNotSupported(exc.NodeCompositionPluginBadRequest):
|
||||
message = _("The NFP Node driver doesn't support operation, "
|
||||
"if instance status is in BUILD state.")
|
||||
|
||||
|
||||
class ServiceNodeInstanceNetworkFunctionMapping(model_base.BASEV2):
|
||||
"""ServiceChainInstance to NFP network function mapping."""
|
||||
|
||||
@ -142,7 +150,9 @@ class ServiceNodeInstanceNetworkFunctionMapping(model_base.BASEV2):
|
||||
sc_node_id = sa.Column(sa.String(36),
|
||||
nullable=False, primary_key=True)
|
||||
network_function_id = sa.Column(sa.String(36),
|
||||
nullable=False, primary_key=True)
|
||||
nullable=True)
|
||||
status = sa.Column(sa.String(20), nullable=True)
|
||||
status_details = sa.Column(sa.String(4096), nullable=True)
|
||||
|
||||
|
||||
class NFPClientApi(object):
|
||||
@ -164,21 +174,23 @@ class NFPClientApi(object):
|
||||
'service_profile']['id']})
|
||||
cctxt = self.client.prepare(
|
||||
fanout=False, topic=nfp_rpc_topics.NFP_NSO_TOPIC)
|
||||
return cctxt.call(
|
||||
return cctxt.cast(
|
||||
context,
|
||||
'create_network_function',
|
||||
network_function=network_function)
|
||||
|
||||
def delete_network_function(self, context, network_function_id):
|
||||
def delete_network_function(self, context, network_function_id,
|
||||
network_function_data):
|
||||
LOG.info(_LI("Sending RPC DELETE NETWORK FUNCTION to Service "
|
||||
"Orchestrator for NF:"
|
||||
"%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(
|
||||
return cctxt.cast(
|
||||
context,
|
||||
'delete_network_function',
|
||||
network_function_id=network_function_id)
|
||||
network_function_id=network_function_id,
|
||||
network_function_data=network_function_data)
|
||||
|
||||
def update_network_function(self, context, network_function_id, config):
|
||||
LOG.info(_LI("Sending RPC UPDATE NETWORK FUNCTION to Service "
|
||||
@ -186,7 +198,7 @@ class NFPClientApi(object):
|
||||
"%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(
|
||||
return cctxt.cast(
|
||||
context,
|
||||
'update_network_function',
|
||||
network_function_id=network_function_id,
|
||||
@ -208,7 +220,7 @@ class NFPClientApi(object):
|
||||
"%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(context,
|
||||
return cctxt.cast(context,
|
||||
'consumer_ptg_added_notification',
|
||||
network_function_id=network_function_id,
|
||||
policy_target_group=policy_target_group)
|
||||
@ -219,7 +231,7 @@ class NFPClientApi(object):
|
||||
" Service Orchestrator for NF:%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(context,
|
||||
return cctxt.cast(context,
|
||||
'consumer_ptg_removed_notification',
|
||||
network_function_id=network_function_id,
|
||||
policy_target_group=policy_target_group)
|
||||
@ -230,7 +242,7 @@ class NFPClientApi(object):
|
||||
"Service Orchestrator for NF:%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(context,
|
||||
return cctxt.cast(context,
|
||||
'policy_target_added_notification',
|
||||
network_function_id=network_function_id,
|
||||
policy_target=policy_target)
|
||||
@ -241,7 +253,7 @@ class NFPClientApi(object):
|
||||
"Service Orchestrator for NF:%(network_function_id)s"),
|
||||
{'network_function_id': network_function_id})
|
||||
cctxt = self.client.prepare(version=self.RPC_API_VERSION)
|
||||
return cctxt.call(context,
|
||||
return cctxt.cast(context,
|
||||
'policy_target_removed_notification',
|
||||
network_function_id=network_function_id,
|
||||
policy_target=policy_target)
|
||||
@ -315,6 +327,7 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
def __init__(self):
|
||||
super(NFPNodeDriver, self).__init__()
|
||||
self._lbaas_plugin = None
|
||||
self.nfp_db = nfp_db.NFPDbBase()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -344,6 +357,14 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
in six.iteritems(service_flavor_dict)}
|
||||
return service_details
|
||||
|
||||
def _update_node_instance_network_function_map(self, context,
|
||||
updated_network_function_map):
|
||||
self.nfp_db.update_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id'],
|
||||
updated_network_function_map)
|
||||
|
||||
def get_plumbing_info(self, context):
|
||||
plumbing_request = {}
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
@ -425,6 +446,14 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
raise InvalidServiceType()
|
||||
self._is_node_order_in_spec_supported(context)
|
||||
|
||||
def _validate_status(self, context):
|
||||
servicechain_instance_id = context.instance['id']
|
||||
servicechain_instance = context.sc_plugin.get_servicechain_instance(
|
||||
context.plugin_context, servicechain_instance_id)
|
||||
if servicechain_instance['status']:
|
||||
if servicechain_instance['status'] == nfp_constants.BUILD:
|
||||
raise OperationNotSupported()
|
||||
|
||||
def validate_update(self, context):
|
||||
NFPContext.store_nfp_context(context.instance['id'],
|
||||
update=True)
|
||||
@ -440,6 +469,7 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
if context.current_profile['service_type'] not in (
|
||||
self.SUPPORTED_SERVICE_TYPES):
|
||||
raise InvalidServiceType()
|
||||
self._validate_status(context)
|
||||
|
||||
def _wait(self, thread, context):
|
||||
try:
|
||||
@ -449,26 +479,40 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
NFPContext.clear_nfp_context(context.instance['id'])
|
||||
raise e
|
||||
|
||||
def _queue_notification(self, context, method, args):
|
||||
LOG.debug("Queuing notification, notifier_method: %s "
|
||||
"arguments: %s" % (method, args))
|
||||
txn = local_api.get_outer_transaction(
|
||||
context.plugin_context.session.transaction)
|
||||
local_api.send_or_queue_notification(
|
||||
context.plugin_context.session,
|
||||
txn, self.nfp_notifier,
|
||||
method, args)
|
||||
|
||||
def create(self, context):
|
||||
try:
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_id = self._create_network_function(context)
|
||||
network_function_id = None
|
||||
status = nfp_constants.BUILD
|
||||
status_details = 'processing create in node driver.'
|
||||
self._create_network_function(context)
|
||||
except Exception:
|
||||
# NFPContext.clear_nfp_context(context.instance['id'])
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
message = "Traceback: %s" % (exc_value)
|
||||
LOG.error(message)
|
||||
network_function_id = ''
|
||||
|
||||
finally:
|
||||
self._set_node_instance_network_function_map(
|
||||
self.nfp_db.create_node_instance_network_function_map(
|
||||
context.plugin_session, context.current_node['id'],
|
||||
context.instance['id'], network_function_id)
|
||||
|
||||
self._wait_for_node_operation_completion(
|
||||
context, network_function_id,
|
||||
nfp_constants.CREATE)
|
||||
context.instance['id'], network_function_id,
|
||||
status, status_details)
|
||||
LOG.info(_LI("Processed create NF in node driver."
|
||||
"servicechain_instance_id: %(sci_id)s, "
|
||||
"servicechain_node_id: %(scn_id)s"), {
|
||||
'sci_id': context.instance['id'],
|
||||
'scn_id': context.current_node['id']})
|
||||
|
||||
def _wait_for_node_operation_completion(self, context, network_function_id,
|
||||
operation):
|
||||
@ -511,10 +555,11 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
NFPContext.clear_nfp_context(context.instance['id'])
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = self._get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id'])
|
||||
network_function_map = (
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id']))
|
||||
|
||||
if not all([network_function_map, context.original_node.get('config'),
|
||||
context.current_node.get('config')]):
|
||||
@ -523,9 +568,6 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
network_function_id = network_function_map.network_function_id
|
||||
self._update(context, network_function_id)
|
||||
|
||||
self._wait_for_network_function_operation_completion(
|
||||
context, network_function_id, operation=nfp_constants.UPDATE)
|
||||
|
||||
def _get_node_count(self, context):
|
||||
current_specs = context.relevant_specs
|
||||
node_list = []
|
||||
@ -535,6 +577,20 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
sc_node_count=len(node_list))
|
||||
return len(node_list)
|
||||
|
||||
def get_status(self, context):
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = (
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id']))
|
||||
nf_status = network_function_map.status
|
||||
if nf_status not in nfp_constants.NFP_STATUS:
|
||||
nf_status = nfp_constants.BUILD
|
||||
status = nfp_constants.NFP_STATUS_MAP[nf_status]
|
||||
return status
|
||||
|
||||
def delete(self, context):
|
||||
nfp_context = (
|
||||
NFPContext.get_nfp_context(context.instance['id']))
|
||||
@ -543,24 +599,23 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = self._get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id'])
|
||||
network_function_id = None
|
||||
if network_function_map:
|
||||
self._delete_node_instance_network_function_map(
|
||||
network_function_map = (
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id'])
|
||||
context.instance['id']))
|
||||
network_function_id = None
|
||||
if network_function_map:
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing node delete'}
|
||||
self._update_node_instance_network_function_map(
|
||||
context, updated_network_function_map)
|
||||
network_function_id = network_function_map.network_function_id
|
||||
|
||||
if network_function_id:
|
||||
try:
|
||||
self.nfp_notifier.delete_network_function(
|
||||
context=context.plugin_context,
|
||||
network_function_id=(
|
||||
network_function_map.network_function_id))
|
||||
self._delete_network_function(context, network_function_id)
|
||||
except Exception:
|
||||
# NFPContext.clear_nfp_context(context.instance['id'])
|
||||
LOG.exception(_LE("Delete Network service Failed"))
|
||||
@ -569,8 +624,6 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
LOG.error(message)
|
||||
|
||||
self._update_ptg(context)
|
||||
self._wait_for_node_operation_completion(context, network_function_id,
|
||||
nfp_constants.DELETE)
|
||||
|
||||
def update_policy_target_added(self, context, policy_target):
|
||||
if context.current_profile['service_type'] == pconst.LOADBALANCERV2:
|
||||
@ -578,18 +631,22 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
return
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map =\
|
||||
self._get_node_instance_network_function_map(
|
||||
network_function_map = (
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id'])
|
||||
context.instance['id']))
|
||||
if network_function_map:
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing PT add'}
|
||||
self._update_node_instance_network_function_map(
|
||||
context, updated_network_function_map)
|
||||
network_function_id = network_function_map.network_function_id
|
||||
self.nfp_notifier.policy_target_added_notification(
|
||||
context.plugin_context, network_function_id, policy_target)
|
||||
self._wait_for_network_function_operation_completion(
|
||||
context, network_function_id,
|
||||
operation=nfp_constants.UPDATE)
|
||||
self._queue_notification(
|
||||
context, 'policy_target_added_notification',
|
||||
[context.plugin_context, network_function_id,
|
||||
policy_target])
|
||||
|
||||
def update_policy_target_removed(self, context, policy_target):
|
||||
if context.current_profile['service_type'] == pconst.LOADBALANCERV2:
|
||||
@ -598,18 +655,22 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = (
|
||||
self._get_node_instance_network_function_map(
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id']))
|
||||
|
||||
if network_function_map:
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing PT remove'}
|
||||
self._update_node_instance_network_function_map(
|
||||
context, updated_network_function_map)
|
||||
network_function_id = network_function_map.network_function_id
|
||||
self.nfp_notifier.policy_target_removed_notification(
|
||||
context.plugin_context, network_function_id, policy_target)
|
||||
self._wait_for_network_function_operation_completion(
|
||||
context, network_function_id,
|
||||
operation=nfp_constants.UPDATE)
|
||||
self._queue_notification(
|
||||
context, 'policy_target_removed_notification',
|
||||
[context.plugin_context, network_function_id,
|
||||
policy_target])
|
||||
|
||||
def notify_chain_parameters_updated(self, context):
|
||||
pass # We are not using the classifier specified in redirect Rule
|
||||
@ -624,20 +685,22 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = (
|
||||
self._get_node_instance_network_function_map(
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id']))
|
||||
|
||||
if network_function_map:
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing consumer add'}
|
||||
self._update_node_instance_network_function_map(context,
|
||||
updated_network_function_map)
|
||||
network_function_id = network_function_map.network_function_id
|
||||
self.nfp_notifier.consumer_ptg_added_notification(
|
||||
context.plugin_context,
|
||||
network_function_id,
|
||||
policy_target_group)
|
||||
self._wait_for_network_function_operation_completion(
|
||||
context, network_function_id,
|
||||
operation=nfp_constants.UPDATE)
|
||||
self._queue_notification(
|
||||
context, 'consumer_ptg_added_notification',
|
||||
[context.plugin_context, network_function_id,
|
||||
policy_target_group])
|
||||
|
||||
def update_node_consumer_ptg_removed(self, context, policy_target_group):
|
||||
# When a group is created which is both consumer and provider.
|
||||
@ -648,20 +711,22 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
context._plugin_context = self._get_resource_owner_context(
|
||||
context._plugin_context)
|
||||
network_function_map = (
|
||||
self._get_node_instance_network_function_map(
|
||||
self.nfp_db.get_node_instance_network_function_map(
|
||||
context.plugin_session,
|
||||
context.current_node['id'],
|
||||
context.instance['id']))
|
||||
|
||||
if network_function_map:
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing consumer remove'}
|
||||
self._update_node_instance_network_function_map(
|
||||
context, updated_network_function_map)
|
||||
network_function_id = network_function_map.network_function_id
|
||||
self.nfp_notifier.consumer_ptg_removed_notification(
|
||||
context.plugin_context,
|
||||
network_function_id,
|
||||
policy_target_group)
|
||||
self._wait_for_network_function_operation_completion(
|
||||
context, network_function_id,
|
||||
operation=nfp_constants.UPDATE)
|
||||
self._queue_notification(
|
||||
context, 'consumer_ptg_removed_notification',
|
||||
[context.plugin_context, network_function_id,
|
||||
policy_target_group])
|
||||
|
||||
def policy_target_group_updated(self, context, old_ptg, current_ptg):
|
||||
if not (old_ptg and current_ptg):
|
||||
@ -815,10 +880,15 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
def _update(self, context, network_function_id):
|
||||
if (context.original_node['config'] != context.current_node['config']):
|
||||
try:
|
||||
self.nfp_notifier.update_network_function(
|
||||
context=context.plugin_context,
|
||||
network_function_id=network_function_id,
|
||||
config=context.current_node['config'])
|
||||
updated_network_function_map = {
|
||||
'status': nfp_constants.BUILD,
|
||||
'status_details': 'node driver processing node update'}
|
||||
self._update_node_instance_network_function_map(
|
||||
context, updated_network_function_map)
|
||||
self._queue_notification(context, 'update_network_function',
|
||||
[context.plugin_context,
|
||||
network_function_id,
|
||||
context.current_node['config']])
|
||||
except Exception:
|
||||
LOG.exception(_LE("Update Network service Failed for "
|
||||
"network function: %(nf_id)s"),
|
||||
@ -1048,9 +1118,9 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
|
||||
return consuming_ptgs_details, consuming_eps_details
|
||||
|
||||
def _create_network_function(self, context):
|
||||
def _get_nfp_network_function(self, context):
|
||||
"""
|
||||
nfp_create_nf_data :-
|
||||
nfp_nf_data :-
|
||||
|
||||
{'resource_owner_context': <>,
|
||||
'service_chain_instance': <>,
|
||||
@ -1068,7 +1138,7 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
}
|
||||
|
||||
"""
|
||||
nfp_create_nf_data = {}
|
||||
nfp_nf_data = {}
|
||||
|
||||
sc_instance = context.instance
|
||||
service_targets = self._get_service_targets(context)
|
||||
@ -1135,7 +1205,7 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
|
||||
service_chain_specs = self._get_service_chain_specs(context)
|
||||
|
||||
nfp_create_nf_data = {
|
||||
nfp_nf_data = {
|
||||
'resource_owner_context': context._plugin_context.to_dict(),
|
||||
'service_chain_instance': sc_instance,
|
||||
'service_chain_node': context.current_node,
|
||||
@ -1150,48 +1220,49 @@ class NFPNodeDriver(driver_base.NodeDriverBase):
|
||||
'consuming_ptgs_details': consuming_ptgs_details,
|
||||
'consuming_eps_details': consuming_eps_details,
|
||||
'service_chain_specs': service_chain_specs}
|
||||
return nfp_nf_data
|
||||
|
||||
def _create_network_function(self, context):
|
||||
nfp_create_nf_data = self._get_nfp_network_function(context)
|
||||
LOG.info(_LI("Received Call CREATE NETWORK FUNCTION for tenant: "
|
||||
"%(tenant_id)s with service profile:"
|
||||
"%(service_profile)s"),
|
||||
{'tenant_id': nfp_create_nf_data['tenant_id'],
|
||||
'service_profile': nfp_create_nf_data['service_profile']})
|
||||
return self.nfp_notifier.create_network_function(
|
||||
context.plugin_context, network_function=nfp_create_nf_data)['id']
|
||||
self._queue_notification(context, 'create_network_function',
|
||||
[context.plugin_context, nfp_create_nf_data])
|
||||
|
||||
def _set_node_instance_network_function_map(
|
||||
self, session, sc_node_id, sc_instance_id, network_function_id):
|
||||
with session.begin(subtransactions=True):
|
||||
sc_node_instance_ns_map = (
|
||||
ServiceNodeInstanceNetworkFunctionMapping(
|
||||
sc_node_id=sc_node_id,
|
||||
sc_instance_id=sc_instance_id,
|
||||
network_function_id=network_function_id))
|
||||
session.add(sc_node_instance_ns_map)
|
||||
def _delete_network_function(self, context, network_function_id):
|
||||
nfp_delete_nf_data = self._get_nfp_network_function(context)
|
||||
self._detach_port_from_pts(context,
|
||||
nfp_delete_nf_data['provider']['pt'])
|
||||
if nfp_delete_nf_data['consumer'].get('pt'):
|
||||
self._detach_port_from_pts(context,
|
||||
nfp_delete_nf_data['consumer']['pt'])
|
||||
LOG.info(_LI("Received Call DELETE NETWORK FUNCTION for tenant: "
|
||||
"%(tenant_id)s with service profile:"
|
||||
"%(service_profile)s"),
|
||||
{'tenant_id': nfp_delete_nf_data['tenant_id'],
|
||||
'service_profile': nfp_delete_nf_data['service_profile']})
|
||||
self._queue_notification(context, 'delete_network_function',
|
||||
[context.plugin_context, network_function_id,
|
||||
nfp_delete_nf_data])
|
||||
|
||||
def _get_node_instance_network_function_map(self, session, sc_node_id=None,
|
||||
sc_instance_id=None):
|
||||
def _detach_port_from_pts(self, context, policy_targets):
|
||||
'''
|
||||
Disassociate port from policy target
|
||||
'''
|
||||
try:
|
||||
with session.begin(subtransactions=True):
|
||||
query = session.query(
|
||||
ServiceNodeInstanceNetworkFunctionMapping)
|
||||
if sc_node_id:
|
||||
query = query.filter_by(sc_node_id=sc_node_id)
|
||||
if sc_instance_id:
|
||||
query = query.filter_by(sc_instance_id=sc_instance_id)
|
||||
return query.first()
|
||||
except NoResultFound:
|
||||
return None
|
||||
for pt in policy_targets:
|
||||
context.gbp_plugin.update_policy_target(
|
||||
context.plugin_context, pt['id'],
|
||||
{'policy_target': {'port_id': None}})
|
||||
LOG.debug('Detached port %s from pt %s' % (pt['id'],
|
||||
pt['port_id']))
|
||||
|
||||
def _delete_node_instance_network_function_map(self, session, sc_node_id,
|
||||
sc_instance_id):
|
||||
with session.begin(subtransactions=True):
|
||||
sc_node_instance_ns_maps = (
|
||||
session.query(ServiceNodeInstanceNetworkFunctionMapping).
|
||||
filter_by(sc_node_id=sc_node_id).
|
||||
filter_by(sc_instance_id=sc_instance_id).
|
||||
all())
|
||||
for sc_node_instance_ns_map in sc_node_instance_ns_maps:
|
||||
session.delete(sc_node_instance_ns_map)
|
||||
except Exception:
|
||||
LOG.warning(_LW("Failed to disassociate port from"
|
||||
" pt: %(pt)s, Error: %(exc)s"), {'pt': pt, 'exc': exc})
|
||||
|
||||
def _update_ptg(self, context):
|
||||
if hasattr(context, 'provider') and context.provider['description']:
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
import copy
|
||||
import fixtures
|
||||
import mock
|
||||
from neutron import context
|
||||
from neutron.db import api as db_api
|
||||
from neutron.tests import base
|
||||
@ -167,6 +168,8 @@ class NFPDBTestCase(SqlTestCase):
|
||||
self.assertEqual([], network_functions)
|
||||
|
||||
def test_update_network_function(self):
|
||||
self.nfp_db.update_node_instance_network_function_map = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
self.assertIsNotNone(network_function['id'])
|
||||
updated_network_function = {'status': 'ERROR'}
|
||||
|
@ -119,9 +119,9 @@ class NSORpcHandlerTestCase(NSOModuleTestCase):
|
||||
def test_rpc_delete_network_function(self, mock_delete_network_function):
|
||||
with mock.patch.object(identity_client, "Client"):
|
||||
self.rpc_handler.delete_network_function(
|
||||
"context", "network_function_id")
|
||||
"context", "network_function_id", mock.ANY)
|
||||
mock_delete_network_function.assert_called_once_with(
|
||||
"context", "network_function_id")
|
||||
"context", "network_function_id", mock.ANY)
|
||||
|
||||
@mock.patch.object(nso.ServiceOrchestrator,
|
||||
"update_network_function")
|
||||
@ -204,6 +204,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_service_profile,
|
||||
mock_get_admin_token,
|
||||
mock_get_admin_tenant_id):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function_info = {
|
||||
'tenant_id': 'tenant_id',
|
||||
'service_chain_id': 'sc_instance_id',
|
||||
@ -302,8 +305,12 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.service_orchestrator._create_event = mock.MagicMock(
|
||||
return_value='')
|
||||
|
||||
delete_network_function_data = {
|
||||
'service_chain_instance': {},
|
||||
'provider': {},
|
||||
'consumer': {}}
|
||||
self.service_orchestrator.delete_network_function(
|
||||
self.context, network_function['id'])
|
||||
self.context, network_function['id'], delete_network_function_data)
|
||||
self.assertRaises(nfp_exc.NetworkFunctionNotFound,
|
||||
self.nfp_db.get_network_function,
|
||||
self.session, network_function['id'])
|
||||
@ -325,6 +332,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_admin_token,
|
||||
mock_create_event,
|
||||
mock_get_admin_tenant_id):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function_instance = self.create_network_function_instance()
|
||||
network_function_id = network_function_instance['network_function_id']
|
||||
network_function = self.nfp_db.get_network_function(
|
||||
@ -336,8 +346,12 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
transport.parse_service_flavor_string = mock.MagicMock(
|
||||
return_value={'device_type': 'VM',
|
||||
'service_vendor': 'vyos'})
|
||||
delete_network_function_data = {
|
||||
'service_chain_instance': {},
|
||||
'provider': {},
|
||||
'consumer': {}}
|
||||
self.service_orchestrator.delete_network_function(
|
||||
self.context, network_function_id)
|
||||
self.context, network_function_id, delete_network_function_data)
|
||||
network_function = self.nfp_db.get_network_function(
|
||||
self.session, network_function_id)
|
||||
self.assertEqual('PENDING_DELETE', network_function['status'])
|
||||
@ -418,6 +432,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.assertIsNotNone(db_nf['config_policy_id'])
|
||||
|
||||
def test_event_handle_device_create_failed(self):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
nfd = self.create_network_function_device()
|
||||
nfi = self.create_network_function_instance(create_nfd=False)
|
||||
request_data = {
|
||||
@ -437,6 +454,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.assertEqual(nfp_constants.ERROR, db_nf['status'])
|
||||
|
||||
def test_event_check_for_user_config_complete(self):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
network_function_details = (
|
||||
self.service_orchestrator.get_network_function_details(
|
||||
@ -518,6 +538,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.assertEqual(status, nso.STOP_POLLING)
|
||||
|
||||
def test_event_handle_user_config_applied(self):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
request_data = {
|
||||
'config_policy_id': 'config_policy_id',
|
||||
@ -530,6 +553,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.assertEqual('ACTIVE', db_nf['status'])
|
||||
|
||||
def test_event_handle_user_config_failed(self):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
request_data = {
|
||||
'config_policy_id': 'config_policy_id',
|
||||
@ -548,6 +574,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
nso.ServiceOrchestrator, "_create_event")
|
||||
def test_event_check_for_user_config_deleted(self, mock_create_event,
|
||||
mock_service_type):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
with mock.patch.object(
|
||||
self.service_orchestrator.config_driver,
|
||||
@ -619,6 +648,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
self.assertEqual(status, nso.STOP_POLLING)
|
||||
|
||||
def test_event_handle_user_config_delete_failed(self):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.create_network_function()
|
||||
request_data = {
|
||||
'network_function_id': network_function['id']
|
||||
@ -654,8 +686,15 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_admin_token.return_value = 'admin_token'
|
||||
mock_get_admin_tenant_id.return_value = 'admin_tenant_id'
|
||||
nfp_context.init()
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
delete_network_function_data = {
|
||||
'service_chain_instance': {},
|
||||
'provider': {},
|
||||
'consumer': {}}
|
||||
self.service_orchestrator.delete_network_function(
|
||||
self.context, network_function['id'])
|
||||
self.context, network_function['id'], delete_network_function_data)
|
||||
db_nf = self.nfp_db.get_network_function(
|
||||
self.session, network_function['id'])
|
||||
self.assertEqual('PENDING_DELETE', db_nf['status'])
|
||||
@ -664,6 +703,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
nso.ServiceOrchestrator, "_create_event")
|
||||
def test_event_delete_network_function_instance(self, mock_create_event):
|
||||
nfi = self.create_network_function_instance()
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
network_function = self.nfp_db.get_network_function(
|
||||
self.session, nfi['network_function_id'])
|
||||
self.assertEqual([nfi['id']],
|
||||
@ -706,6 +748,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_service_profile,
|
||||
mock_get_admin_token,
|
||||
mock_create_event):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
nfi = self.create_network_function_instance()
|
||||
network_function_id = nfi['network_function_id']
|
||||
policy_target = mock.Mock()
|
||||
@ -735,6 +780,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_service_profile,
|
||||
mock_get_admin_token,
|
||||
mock_create_event):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
nfi = self.create_network_function_instance()
|
||||
network_function_id = nfi['network_function_id']
|
||||
policy_target = mock.Mock()
|
||||
@ -763,6 +811,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_service_profile,
|
||||
mock_get_admin_token,
|
||||
mock_create_event):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
nfi = self.create_network_function_instance()
|
||||
network_function_id = nfi['network_function_id']
|
||||
policy_target_group = mock.Mock()
|
||||
@ -809,6 +860,9 @@ class ServiceOrchestratorTestCase(NSOModuleTestCase):
|
||||
mock_get_service_profile,
|
||||
mock_get_admin_token,
|
||||
mock_create_event):
|
||||
(self.service_orchestrator.db_handler.
|
||||
update_node_instance_network_function_map) = mock.MagicMock(
|
||||
return_value=None)
|
||||
nfi = self.create_network_function_instance()
|
||||
network_function_id = nfi['network_function_id']
|
||||
policy_target_group = mock.Mock()
|
||||
|
@ -18,7 +18,6 @@ from neutron_lib.db import model_base
|
||||
from oslo_serialization import jsonutils
|
||||
import webob
|
||||
|
||||
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import (
|
||||
plugin as ncp_plugin)
|
||||
from gbpservice.neutron.services.servicechain.plugins.ncp import config # noqa
|
||||
@ -31,6 +30,7 @@ from gbpservice.neutron.tests.unit.services.servicechain import (
|
||||
base_test_servicechain_plugin as test_base)
|
||||
from gbpservice.neutron.tests.unit.services.servicechain.ncp import (
|
||||
test_ncp_plugin as test_ncp_plugin)
|
||||
from gbpservice.nfp.orchestrator.db import nfp_db as nfp_db
|
||||
|
||||
SERVICE_DELETE_TIMEOUT = 15
|
||||
SVC_MANAGEMENT_PTG = 'foo'
|
||||
@ -264,6 +264,10 @@ class NFPNodeDriverTestCase(
|
||||
pass
|
||||
|
||||
|
||||
class DummyMap(object):
|
||||
network_function_id = '12'
|
||||
|
||||
|
||||
class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
|
||||
@mock.patch.object(nfp_node_driver.NFPClientApi, 'get_plumbing_info')
|
||||
@ -286,10 +290,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
'plumbing_type': 'gateway'
|
||||
}
|
||||
self._create_simple_fw_service_chain()
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
|
||||
def _test_node_update(self):
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
@ -323,10 +324,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
node['id'],
|
||||
name='newname',
|
||||
expected_res_status=200)
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
update_svc_config.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(nfp_node_driver.NFPClientApi, 'get_plumbing_info')
|
||||
@ -342,6 +340,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
create_nf.return_value = {
|
||||
'id': '126231632163'
|
||||
}
|
||||
|
||||
plumbing_info.return_value = {
|
||||
'management': [],
|
||||
'provider': [{}],
|
||||
@ -366,25 +365,22 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
provider = self.create_policy_target_group(
|
||||
provided_policy_rule_sets={prs['id']: ''})[
|
||||
'policy_target_group']
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"get_network_function") as get_nf:
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"delete_network_function") as delete_nf:
|
||||
"delete_network_function") as delete_nf,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"get_node_instance_network_function_map") as get_map,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"update_node_instance_network_function_map") as update_map:
|
||||
|
||||
get_map.return_value = DummyMap()
|
||||
update_map.return_value = mock.ANY
|
||||
get_nf.return_value = None
|
||||
self.delete_policy_target_group(
|
||||
provider['id'], expected_res_status=204)
|
||||
expected_plugin_context = mock.ANY
|
||||
expected_network_function_id = mock.ANY
|
||||
expected_plugin_context = mock.ANY
|
||||
get_nf.assert_called_once_with(
|
||||
expected_plugin_context,
|
||||
expected_network_function_id)
|
||||
delete_nf.assert_called_once_with(
|
||||
context=mock.ANY,
|
||||
network_function_id=mock.ANY)
|
||||
provider['id'], expected_res_status=204)
|
||||
delete_nf.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY)
|
||||
|
||||
@mock.patch.object(nfp_node_driver.NFPClientApi, 'get_plumbing_info')
|
||||
def test_wait_for_network_function_delete_completion(self, plumbing_info):
|
||||
@ -423,14 +419,20 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
provider = self.create_policy_target_group(
|
||||
provided_policy_rule_sets={prs['id']: ''})[
|
||||
'policy_target_group']
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
'delete_network_function') as delete_nf:
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
'get_network_function') as get_nf:
|
||||
'get_network_function') as get_nf,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"get_node_instance_network_function_map") as get_map,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"update_node_instance_network_function_map") as \
|
||||
update_map:
|
||||
|
||||
get_map.return_value = DummyMap()
|
||||
update_map.return_value = mock.ANY
|
||||
delete_nf.return_value = None
|
||||
get_nf.return_value = None
|
||||
# Removing the PRSs will make the PTG deletable again
|
||||
@ -440,9 +442,8 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
expected_res_status=200)
|
||||
self.delete_policy_target_group(provider['id'],
|
||||
expected_res_status=204)
|
||||
delete_nf.assert_called_once_with(context=mock.ANY,
|
||||
network_function_id=mock.ANY)
|
||||
get_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
delete_nf.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
mock.ANY)
|
||||
|
||||
def _create_policy_target_port(self, policy_target_group_id):
|
||||
pt = self.create_policy_target(
|
||||
@ -503,10 +504,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
self.create_policy_target_group(
|
||||
consumed_policy_rule_sets={prs['id']: ''})
|
||||
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
|
||||
def test_invalid_service_type_rejected(self):
|
||||
node_used = self._nfp_create_profiled_servicechain_node(
|
||||
@ -611,21 +609,25 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
spec = self.create_servicechain_spec(
|
||||
nodes=node_ids,
|
||||
expected_res_status=201)['servicechain_spec']
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"get_network_function") as get_nf:
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"delete_network_function") as delete_nf:
|
||||
"delete_network_function") as delete_nf,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"get_node_instance_network_function_map") as get_map,\
|
||||
mock.patch.object(nfp_db.NFPDbBase,
|
||||
"update_node_instance_network_function_map") as \
|
||||
update_map:
|
||||
get_map.return_value = DummyMap()
|
||||
update_map.return_value = mock.ANY
|
||||
get_nf.return_value = None
|
||||
res = self.update_servicechain_instance(
|
||||
servicechain_instance['id'],
|
||||
servicechain_specs=[spec['id']],
|
||||
expected_res_status=webob.exc.HTTPBadRequest.code)
|
||||
get_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
delete_nf.assert_called_once_with(context=mock.ANY,
|
||||
network_function_id=mock.ANY)
|
||||
delete_nf.assert_called_once_with(mock.ANY,
|
||||
mock.ANY, mock.ANY)
|
||||
self.assertEqual('NoDriverAvailableForAction',
|
||||
res['NeutronError']['type'])
|
||||
|
||||
@ -666,10 +668,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
self.create_policy_target_group(
|
||||
provided_policy_rule_sets={prs['id']: ''})[
|
||||
'policy_target_group']
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"consumer_ptg_added_notification") as ptg_added:
|
||||
self.create_policy_target_group(
|
||||
@ -716,10 +715,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
'policy_target_group']
|
||||
ptg_added.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
mock.ANY)
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
|
||||
with mock.patch.object(nfp_node_driver.NFPClientApi,
|
||||
"consumer_ptg_removed_notification") as ptg_removed:
|
||||
@ -778,10 +774,7 @@ class TestServiceChainInstance(NFPNodeDriverTestCase):
|
||||
pt = self.create_policy_target(
|
||||
policy_target_group_id=provider['id'])[
|
||||
'policy_target']
|
||||
create_nf.assert_called_once_with(
|
||||
mock.ANY,
|
||||
network_function=mock.ANY)
|
||||
get_nf.assert_called_with(mock.ANY, mock.ANY)
|
||||
create_nf.assert_called_once_with(mock.ANY, mock.ANY)
|
||||
pt_added.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
mock.ANY)
|
||||
|
||||
|
@ -53,7 +53,9 @@ PENDING_CREATE = "PENDING_CREATE"
|
||||
PENDING_UPDATE = "PENDING_UPDATE"
|
||||
PENDING_DELETE = "PENDING_DELETE"
|
||||
ERROR = "ERROR"
|
||||
BUILD = "BUILD"
|
||||
|
||||
NFP_STATUS = [ACTIVE, PENDING_CREATE, PENDING_UPDATE, PENDING_DELETE, ERROR]
|
||||
DEVICE_ORCHESTRATOR = "device_orch"
|
||||
SERVICE_ORCHESTRATOR = "service_orch"
|
||||
|
||||
@ -134,3 +136,18 @@ STACK_ACTION_WAIT_TIME = 300
|
||||
|
||||
# default directory for config files
|
||||
CONFIG_DIR = '/etc/nfp/'
|
||||
|
||||
NFP_STATUS_MAP = {
|
||||
ERROR: {'status': ERROR,
|
||||
'status_details': 'Node deployment failed'},
|
||||
ACTIVE: {'status': ACTIVE,
|
||||
'status_details': 'Node deployment completed'},
|
||||
BUILD: {'status': BUILD,
|
||||
'status_details': 'Node deployment is in progress'},
|
||||
PENDING_CREATE: {'status': BUILD,
|
||||
'status_details': 'Node deployment is in progress'},
|
||||
PENDING_UPDATE: {'status': BUILD,
|
||||
'status_details': 'update of node is in progress'},
|
||||
PENDING_DELETE: {'status': BUILD,
|
||||
'status_details': 'delete of node is in progress'}
|
||||
}
|
||||
|
@ -256,14 +256,13 @@ class HeatDriver(object):
|
||||
return
|
||||
|
||||
def _get_provider_ptg_info(self, auth_token, sci_id):
|
||||
with nfp_ctx_mgr.GBPContextManager as gcm:
|
||||
servicechain_instance = gcm.retry(
|
||||
self.gbp_client.get_servicechain_instance,
|
||||
auth_token, sci_id)
|
||||
nfp_context = module_context.get()
|
||||
with nfp_ctx_mgr.GBPContextManager:
|
||||
servicechain_instance = nfp_context.get('service_chain_instance')
|
||||
provider_ptg_id = servicechain_instance['provider_ptg_id']
|
||||
provider_ptg = gcm.retry(self.gbp_client.get_policy_target_group,
|
||||
auth_token, provider_ptg_id)
|
||||
return provider_ptg
|
||||
for ptg in nfp_context['provider']['ptg']:
|
||||
if ptg['id'] == provider_ptg_id:
|
||||
return ptg
|
||||
|
||||
def _pre_stack_cleanup(self, network_function):
|
||||
nfp_context = module_context.get()
|
||||
@ -340,7 +339,15 @@ class HeatDriver(object):
|
||||
return lb_vip, lb_vip_name
|
||||
|
||||
def _get_lb_service_targets(self, auth_token, provider):
|
||||
nfp_context = module_context.get()
|
||||
service_targets = []
|
||||
if 'delete' in nfp_context['log_context']['path']:
|
||||
for policy_target in nfp_context['provider']['pt']:
|
||||
if ('endpoint' in policy_target['name'] and
|
||||
self._is_service_target(policy_target)):
|
||||
service_targets.append(policy_target)
|
||||
return service_targets
|
||||
|
||||
if provider.get("policy_targets"):
|
||||
filters = {'id': provider.get("policy_targets")}
|
||||
else:
|
||||
@ -367,14 +374,6 @@ class HeatDriver(object):
|
||||
if not (lb_vip and service_targets):
|
||||
return None
|
||||
|
||||
for service_target in service_targets:
|
||||
service_target_id = service_target['id']
|
||||
policy_target_info = {'cluster_id': ''}
|
||||
with nfp_ctx_mgr.GBPContextManager as gcm:
|
||||
gcm.retry(self.gbp_client.update_policy_target,
|
||||
admin_token,
|
||||
service_target_id, policy_target_info)
|
||||
|
||||
def _get_provider_pt(self, auth_token, provider):
|
||||
if provider.get("policy_targets"):
|
||||
filters = {'id': provider.get("policy_targets")}
|
||||
|
@ -57,6 +57,7 @@ class Pt(object):
|
||||
if self.data:
|
||||
return {
|
||||
'id': self.data.get('id'),
|
||||
'name': self.data.get('name'),
|
||||
'port_id': self.data.get('port_id'),
|
||||
'policy_target_group_id': self.data.get(
|
||||
'policy_target_group_id'),
|
||||
@ -312,7 +313,8 @@ class ServiceChainInstance(object):
|
||||
return {
|
||||
'id': self.data.get('id'),
|
||||
'config_param_values': self.data.get('config_param_values'),
|
||||
'name': self.data.get('name')
|
||||
'name': self.data.get('name'),
|
||||
'provider_ptg_id': self.data.get('provider_ptg_id')
|
||||
}
|
||||
return self.data
|
||||
|
||||
|
@ -60,6 +60,18 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
|
||||
network_function_db = self._get_network_function(
|
||||
session, network_function_id)
|
||||
network_function_db.update(updated_network_function)
|
||||
if 'status' in updated_network_function.keys():
|
||||
updated_network_function_map = {
|
||||
'status': updated_network_function['status']
|
||||
}
|
||||
if updated_network_function.get('status_description'):
|
||||
updated_network_function_map.update(
|
||||
{'status_details': updated_network_function[
|
||||
'status_description']})
|
||||
self.update_node_instance_network_function_map(session,
|
||||
network_function_db['service_id'],
|
||||
network_function_db['service_chain_id'],
|
||||
updated_network_function_map)
|
||||
return self._make_network_function_dict(network_function_db)
|
||||
|
||||
def delete_network_function(self, session, network_function_id):
|
||||
@ -67,6 +79,9 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
|
||||
network_function_db = self._get_network_function(
|
||||
session, network_function_id)
|
||||
session.delete(network_function_db)
|
||||
# deleting sc-node-instance-nf entry
|
||||
self.delete_node_instance_network_function_map(
|
||||
session, network_function_id)
|
||||
|
||||
def get_network_function(self, session, network_function_id, fields=None):
|
||||
service = self._get_network_function(session, network_function_id)
|
||||
@ -696,3 +711,69 @@ class NFPDbBase(common_db_mixin.CommonDbMixin):
|
||||
'secondary_instance_gw_pt': gw['secondary_instance_gw_pt'],
|
||||
'primary_gw_vip_pt': gw['primary_gw_vip_pt'],
|
||||
'secondary_gw_vip_pt': gw['secondary_gw_vip_pt']}
|
||||
|
||||
def create_node_instance_network_function_map(self, session,
|
||||
sc_node_id, sc_instance_id,
|
||||
network_function_id,
|
||||
status, status_details):
|
||||
with session.begin(subtransactions=True):
|
||||
sc_node_instance_ns_map = (
|
||||
nfp_db_model.ServiceNodeInstanceNetworkFunctionMapping(
|
||||
sc_node_id=sc_node_id,
|
||||
sc_instance_id=sc_instance_id,
|
||||
network_function_id=network_function_id,
|
||||
status=status,
|
||||
status_details=status_details))
|
||||
session.add(sc_node_instance_ns_map)
|
||||
|
||||
def update_node_instance_network_function_map(
|
||||
self, session, sc_node_id, sc_instance_id,
|
||||
updated_node_instance_network_function_map):
|
||||
with session.begin(subtransactions=True):
|
||||
node_instance_network_function_map = (
|
||||
self.get_node_instance_network_function_map(session,
|
||||
sc_node_id, sc_instance_id))
|
||||
node_instance_network_function_map.update(
|
||||
updated_node_instance_network_function_map)
|
||||
return node_instance_network_function_map
|
||||
|
||||
def get_node_instance_network_function_map(self, session, sc_node_id=None,
|
||||
sc_instance_id=None):
|
||||
try:
|
||||
with session.begin(subtransactions=True):
|
||||
query = session.query(
|
||||
nfp_db_model.ServiceNodeInstanceNetworkFunctionMapping)
|
||||
if sc_node_id:
|
||||
query = query.filter_by(sc_node_id=sc_node_id)
|
||||
if sc_instance_id:
|
||||
query = query.filter_by(sc_instance_id=sc_instance_id)
|
||||
return query.first()
|
||||
except exc.NoResultFound:
|
||||
return None
|
||||
|
||||
def get_node_instance_network_function_maps(self, session, sc_instance_id):
|
||||
try:
|
||||
with session.begin(subtransactions=True):
|
||||
query = session.query(
|
||||
nfp_db_model.ServiceNodeInstanceNetworkFunctionMapping)
|
||||
query = query.filter_by(sc_instance_id=sc_instance_id)
|
||||
from neutron.db import sqlalchemyutils
|
||||
collection = sqlalchemyutils.paginate_query(
|
||||
query,
|
||||
nfp_db_model.ServiceNodeInstanceNetworkFunctionMapping,
|
||||
None, None)
|
||||
return [item for item in collection]
|
||||
except exc.NoResultFound:
|
||||
return []
|
||||
|
||||
def delete_node_instance_network_function_map(self, session,
|
||||
network_function_id):
|
||||
try:
|
||||
with session.begin(subtransactions=True):
|
||||
sc_node_instance_ns_maps = (session.query(
|
||||
nfp_db_model.ServiceNodeInstanceNetworkFunctionMapping).
|
||||
filter_by(network_function_id=network_function_id).all())
|
||||
for sc_node_instance_ns_map in sc_node_instance_ns_maps:
|
||||
session.delete(sc_node_instance_ns_map)
|
||||
except exc.NoResultFound:
|
||||
return None
|
||||
|
@ -168,3 +168,16 @@ class ServiceGatewayDetails(BASE, model_base.HasId):
|
||||
secondary_instance_gw_pt = sa.Column(sa.String(36), nullable=True)
|
||||
primary_gw_vip_pt = sa.Column(sa.String(36), nullable=True)
|
||||
secondary_gw_vip_pt = sa.Column(sa.String(36), nullable=True)
|
||||
|
||||
|
||||
class ServiceNodeInstanceNetworkFunctionMapping(BASE, model_base.BASEV2):
|
||||
"""ServiceChainInstance to NFP network function mapping."""
|
||||
|
||||
__tablename__ = 'ncp_node_instance_network_function_mappings'
|
||||
sc_instance_id = sa.Column(sa.String(36),
|
||||
nullable=False, primary_key=True)
|
||||
sc_node_id = sa.Column(sa.String(36),
|
||||
nullable=False, primary_key=True)
|
||||
network_function_id = sa.Column(sa.String(36), nullable=True)
|
||||
status = sa.Column(sa.String(50), nullable=True)
|
||||
status_details = sa.Column(sa.String(4096), nullable=True)
|
||||
|
@ -860,21 +860,121 @@ class OrchestrationDriver(object):
|
||||
|
||||
with nfp_ctx_mgr.NovaContextManager.new(suppress=(Exception,)) as ncm:
|
||||
for port in device_data['ports']:
|
||||
port_id = network_handler.get_port_id(token, port['id'])
|
||||
port_id = self._get_port_from_pt(device_data, port['id'])
|
||||
ncm.retry(self.compute_handler_nova.detach_interface,
|
||||
token,
|
||||
device_data['tenant_id'],
|
||||
device_data['id'],
|
||||
port_id)
|
||||
return True
|
||||
# Async change
|
||||
self._delete_port(token, port_id)
|
||||
# Async change: Delete stale l2ps
|
||||
try:
|
||||
self._delete_l2ps(token, device_data, network_handler)
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
def _delete_l2ps(self, token, device_data, network_handler):
|
||||
'''
|
||||
delete l2 policies
|
||||
'''
|
||||
gbp_cli = network_handler.network_handler
|
||||
for ptg in device_data['provider']['ptg']:
|
||||
try:
|
||||
ptg_details = gbp_cli.get_policy_target_group(token,
|
||||
ptg['id'])
|
||||
if ptg_details:
|
||||
LOG.debug('Provider ptg is in use !!')
|
||||
continue
|
||||
except Exception:
|
||||
LOG.debug('Provider not found !!')
|
||||
with nfp_ctx_mgr.GBPContextManager as gcm:
|
||||
l2p = gbp_cli.get_l2_policy(token, ptg['l2_policy_id'])
|
||||
# deleting l2p if it is created implicitly
|
||||
if 'Implicitly' in l2p['description']:
|
||||
gcm.retry(gbp_cli.delete_l2_policy, token,
|
||||
ptg['l2_policy_id'])
|
||||
|
||||
if ('consumer' not in device_data.keys() or not device_data[
|
||||
'consumer'].get('ptg')):
|
||||
return
|
||||
|
||||
for ptg in device_data['consumer']['ptg']:
|
||||
try:
|
||||
ptg_details = gbp_cli.get_policy_target_group(token,
|
||||
ptg['id'])
|
||||
if ptg_details:
|
||||
LOG.debug('Stitching PTG is in use !!')
|
||||
continue
|
||||
except Exception:
|
||||
LOG.debug('Stitching PTG not found !!')
|
||||
with nfp_ctx_mgr.GBPContextManager as gcm:
|
||||
l2p = gbp_cli.get_l2_policy(token, ptg['l2_policy_id'])
|
||||
# deleting l2p if it is created implicitly
|
||||
if 'Implicitly' in l2p['description']:
|
||||
gcm.retry(gbp_cli.delete_l2_policy, token,
|
||||
ptg['l2_policy_id'])
|
||||
|
||||
def _delete_port(self, token, port_id):
|
||||
'''
|
||||
delete neutron port
|
||||
'''
|
||||
try:
|
||||
network_handler = self.network_handlers[nfp_constants.NEUTRON_MODE]
|
||||
network_handler.delete_port(token, port_id)
|
||||
except Exception as exc:
|
||||
LOG.error(_LE("Failed to delete port %(port_id)s. Error: %(exc)s"),
|
||||
{"port_id": port_id, 'exc': exc})
|
||||
|
||||
def _get_port_from_pt(self, device_data, pt_id):
|
||||
'''
|
||||
get neutron_port_id from pt_id using data
|
||||
'''
|
||||
port_id = None
|
||||
for pt in device_data['provider']['pt']:
|
||||
if pt['id'] == pt_id:
|
||||
return pt['port_id']
|
||||
|
||||
if not device_data['consumer'].get('pt'):
|
||||
return port_id
|
||||
|
||||
for pt in device_data['consumer']['pt']:
|
||||
if pt['id'] == pt_id:
|
||||
return pt['port_id']
|
||||
LOG.error(_LE('Policy Target %(pt_id) not found in provided data'),
|
||||
{'pt_id': pt_id})
|
||||
return port_id
|
||||
|
||||
def get_port_details(self, port_id, port_model, data):
|
||||
'''
|
||||
function to retrieve port details from data
|
||||
'''
|
||||
if 'gbp' in port_model:
|
||||
for pt in data['pt']:
|
||||
if port_id == pt['id']:
|
||||
port_id = pt['port_id']
|
||||
break
|
||||
|
||||
for port in data['port']:
|
||||
if port_id == port['id']:
|
||||
ip = port['fixed_ips'][0]['ip_address']
|
||||
mac = port['mac_address']
|
||||
cidr = data['subnet']['cidr']
|
||||
gateway_ip = data['subnet']['gateway_ip']
|
||||
return (ip, mac, cidr, gateway_ip, port, data['subnet'])
|
||||
|
||||
@_set_network_handler
|
||||
def get_delete_device_data(self, device_data, network_handler=None):
|
||||
def get_delete_device_data(self, device_data, network_handler=None,
|
||||
devices_data=None):
|
||||
""" Get the configuration information for NFD
|
||||
|
||||
:param device_data: NFD
|
||||
:type device_data: dict
|
||||
|
||||
:param devices_data: metadata of NFD and NF
|
||||
:type device_data: dict
|
||||
|
||||
:returns: None -- On Failure
|
||||
:returns: dict
|
||||
|
||||
@ -923,7 +1023,8 @@ class OrchestrationDriver(object):
|
||||
if port['port_classification'] == nfp_constants.PROVIDER:
|
||||
try:
|
||||
(provider_ip, provider_mac, provider_cidr, dummy, _, _) = (
|
||||
network_handler.get_port_details(token, port['id'])
|
||||
self.get_port_details(port['id'], port['port_model'],
|
||||
devices_data['provider'])
|
||||
)
|
||||
except Exception:
|
||||
LOG.error(_LE('Failed to get provider port details'
|
||||
@ -933,7 +1034,8 @@ class OrchestrationDriver(object):
|
||||
try:
|
||||
(consumer_ip, consumer_mac, consumer_cidr,
|
||||
consumer_gateway_ip, _, _) = (
|
||||
network_handler.get_port_details(token, port['id'])
|
||||
self.get_port_details(port['id'], port['port_model'],
|
||||
devices_data['consumer'])
|
||||
)
|
||||
except Exception:
|
||||
LOG.error(_LE('Failed to get consumer port details'
|
||||
@ -951,7 +1053,8 @@ class OrchestrationDriver(object):
|
||||
@_set_network_handler
|
||||
def get_network_function_device_config(self, device_data,
|
||||
resource_type, is_delete=False,
|
||||
network_handler=None):
|
||||
network_handler=None,
|
||||
devices_data=None):
|
||||
""" Get the configuration information for NFD
|
||||
|
||||
:returns: dict
|
||||
@ -960,7 +1063,8 @@ class OrchestrationDriver(object):
|
||||
|
||||
if is_delete:
|
||||
device_data = self.get_delete_device_data(
|
||||
device_data, network_handler=network_handler)
|
||||
device_data, network_handler=network_handler,
|
||||
devices_data=devices_data)
|
||||
if not device_data:
|
||||
return None
|
||||
|
||||
|
@ -160,8 +160,7 @@ class RpcHandler(object):
|
||||
# nfp_context = request_info.get('nfp_context')
|
||||
nfp_context['log_context'] = logging_context
|
||||
if 'nfp_context' in request_info:
|
||||
nfp_context['event_desc'] = request_info[
|
||||
'nfp_context'].get('event_desc', {})
|
||||
nfp_context.update(request_info['nfp_context'])
|
||||
|
||||
for response in responses:
|
||||
resource = response.get('resource')
|
||||
@ -1343,9 +1342,11 @@ class DeviceOrchestrator(nfp_api.NfpEventHandler):
|
||||
device = event.data
|
||||
orchestration_driver = self._get_orchestration_driver(
|
||||
device['service_details']['service_vendor'])
|
||||
nfp_context = module_context.get()
|
||||
config_params = (
|
||||
orchestration_driver.get_network_function_device_config(
|
||||
device, nfp_constants.GENERIC_CONFIG, is_delete=True))
|
||||
device, nfp_constants.GENERIC_CONFIG, is_delete=True,
|
||||
devices_data=nfp_context))
|
||||
if not config_params:
|
||||
self._create_event(event_id='DRIVER_ERROR',
|
||||
event_data=device,
|
||||
@ -1366,6 +1367,13 @@ class DeviceOrchestrator(nfp_api.NfpEventHandler):
|
||||
# unplug_interfaces and device delete to delete vms.
|
||||
return None
|
||||
|
||||
nf_data = {
|
||||
'service_chain_instance': nfp_context.get(
|
||||
'service_chain_instance'),
|
||||
'provider': nfp_context.get('provider'),
|
||||
'consumer': nfp_context.get('consumer')
|
||||
}
|
||||
device.update(nf_data)
|
||||
# Sends RPC call to configurator to delete generic config API
|
||||
self.configurator_rpc.delete_network_function_device_config(
|
||||
device, config_params)
|
||||
|
@ -174,7 +174,8 @@ class RpcHandler(object):
|
||||
context, network_function_id, config)
|
||||
|
||||
@log_helpers.log_method_call
|
||||
def delete_network_function(self, context, network_function_id):
|
||||
def delete_network_function(self, context, network_function_id,
|
||||
network_function_data):
|
||||
'''Delete the network Function.
|
||||
|
||||
Invoked in an RPC call. Return the updated Network function DB object.
|
||||
@ -187,7 +188,7 @@ class RpcHandler(object):
|
||||
|
||||
service_orchestrator = ServiceOrchestrator(self._controller, self.conf)
|
||||
service_orchestrator.delete_network_function(
|
||||
context, network_function_id)
|
||||
context, network_function_id, network_function_data)
|
||||
|
||||
@log_helpers.log_method_call
|
||||
def policy_target_added_notification(self, context, network_function_id,
|
||||
@ -378,8 +379,7 @@ class RpcHandlerConfigurator(object):
|
||||
logging_context = request_info.get('logging_context', {})
|
||||
nfp_context['log_context'] = logging_context
|
||||
if 'nfp_context' in request_info:
|
||||
nfp_context['event_desc'] = request_info[
|
||||
'nfp_context'].get('event_desc', {})
|
||||
nfp_context.update(request_info['nfp_context'])
|
||||
|
||||
serialize = False
|
||||
|
||||
@ -944,6 +944,16 @@ class ServiceOrchestrator(nfp_api.NfpEventHandler):
|
||||
self.db_session, network_function)
|
||||
network_function.pop('service_config')
|
||||
|
||||
# Update ncp_node_instance_nf_mapping with nf_id
|
||||
network_function_map = {
|
||||
'network_function_id': network_function['id'],
|
||||
'status': nfp_constants.PENDING_CREATE,
|
||||
'status_details': 'Processing create in orchestrator'
|
||||
}
|
||||
with nfp_ctx_mgr.DbContextManager:
|
||||
self.db_handler.update_node_instance_network_function_map(
|
||||
self.db_session, service_id, service_chain_id,
|
||||
network_function_map)
|
||||
nfp_path.create_path(network_function['id'])
|
||||
nfp_context['event_desc']['path_type'] = 'create'
|
||||
nfp_context['event_desc']['path_key'] = network_function['id']
|
||||
@ -1007,7 +1017,8 @@ class ServiceOrchestrator(nfp_api.NfpEventHandler):
|
||||
user_config,
|
||||
operation='update')
|
||||
|
||||
def delete_network_function(self, context, network_function_id):
|
||||
def delete_network_function(self, context, network_function_id,
|
||||
network_function_data):
|
||||
nfp_context = module_context.get()
|
||||
nfp_path.delete_path(network_function_id)
|
||||
nfp_context['event_desc']['path_type'] = 'delete'
|
||||
@ -1062,6 +1073,13 @@ class ServiceOrchestrator(nfp_api.NfpEventHandler):
|
||||
network_function = {
|
||||
'status': nfp_constants.PENDING_DELETE
|
||||
}
|
||||
service_chain_instance_details = {
|
||||
'service_chain_instance': network_function_data[
|
||||
'service_chain_instance'],
|
||||
'provider': network_function_data['provider'],
|
||||
'consumer': network_function_data['consumer']
|
||||
}
|
||||
network_function_details.update(service_chain_instance_details)
|
||||
with nfp_ctx_mgr.DbContextManager as dcm:
|
||||
network_function = dcm.lock(
|
||||
self.db_session,
|
||||
@ -2537,6 +2555,13 @@ class NSOConfiguratorRpcApi(object):
|
||||
'key': nfp_context.pop('key', None),
|
||||
'id': nfp_context.pop('id', None),
|
||||
'base_mode': nfp_context.pop('base_mode', None)}
|
||||
nf_data = {
|
||||
'service_chain_instance': nfp_context.get(
|
||||
'service_chain_instance'),
|
||||
'provider': nfp_context.get('provider'),
|
||||
'consumer': nfp_context.get('consumer')
|
||||
}
|
||||
rpc_nfp_context.update(nf_data)
|
||||
request_info = {
|
||||
'nf_id': network_function_details['network_function']['id'],
|
||||
'nfi_id': (network_function_instance['id']
|
||||
|
@ -20,6 +20,7 @@ EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
|
||||
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
|
||||
|
||||
source $TOP_DIR/openrc neutron service
|
||||
source $TOP_DIR/exercises/nfp_lib.sh
|
||||
|
||||
create_gbp_resources() {
|
||||
gbp servicechain-node-create --service-profile base_mode_fw --template-file $TOP_DIR/nfp-templates/fw_template.yml FWNODE
|
||||
@ -36,6 +37,8 @@ create_gbp_resources() {
|
||||
gbp policy-rule-set-create --policy-rules "fw-web-redirect-rule fw-web-allow-rule-tcp fw-web-allow-rule-udp fw-web-allow-rule-icmp" fw-webredirect-ruleset
|
||||
gbp group-create fw-consumer --consumed-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
gbp group-create fw-provider --provided-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw-provider 600
|
||||
}
|
||||
|
||||
delete_gbp_resources() {
|
||||
@ -53,6 +56,8 @@ delete_gbp_resources() {
|
||||
gbp policy-action-delete allow-to-fw
|
||||
gbp servicechain-spec-delete fw-chainspec
|
||||
gbp servicechain-node-delete FWNODE
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
}
|
||||
|
||||
validate_gbp_resources() {
|
||||
@ -102,6 +107,8 @@ update_gbp_resources() {
|
||||
#fi
|
||||
|
||||
gbp group-delete fw-provider
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
gbp group-delete fw-consumer
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "0" ]; then
|
||||
@ -119,8 +126,10 @@ update_gbp_resources() {
|
||||
else
|
||||
echo "Chain not deleted"
|
||||
fi
|
||||
|
||||
|
||||
gbp group-update fw-provider --provided-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw-provider 600
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "1" ]; then
|
||||
echo "Chain created"
|
||||
|
@ -20,6 +20,7 @@ EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
|
||||
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
|
||||
|
||||
source $TOP_DIR/openrc neutron service
|
||||
source $TOP_DIR/exercises/nfp_lib.sh
|
||||
|
||||
create_gbp_resources() {
|
||||
# E-W insertion
|
||||
@ -33,6 +34,8 @@ create_gbp_resources() {
|
||||
gbp network-service-policy-create --network-service-params type=ip_single,name=vip_ip,value=self_subnet fw_lb_nsp
|
||||
gbp group-create fw_lb-consumer --consumed-policy-rule-sets "fw_lb-webredirect-ruleset=None"
|
||||
gbp group-create fw_lb-provider --provided-policy-rule-sets "fw_lb-webredirect-ruleset=None" --network-service-policy fw_lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw_lb-provider 600
|
||||
}
|
||||
|
||||
delete_gbp_resources() {
|
||||
@ -46,6 +49,8 @@ delete_gbp_resources() {
|
||||
gbp servicechain-spec-delete fw_lb_chainspec
|
||||
gbp servicechain-node-delete FW_LB-LBNODE
|
||||
gbp servicechain-node-delete FW_LB-FWNODE
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
}
|
||||
|
||||
validate_gbp_resources() {
|
||||
@ -109,7 +114,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group fw_lb-provider provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -118,7 +124,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group fw_lb-provider provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "2" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -127,7 +134,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
@ -136,7 +144,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "0" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
@ -157,6 +166,8 @@ update_gbp_resources() {
|
||||
#fi
|
||||
|
||||
gbp group-delete fw_lb-provider
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
gbp group-delete fw_lb-consumer
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw_lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "0" ]; then
|
||||
@ -174,8 +185,10 @@ update_gbp_resources() {
|
||||
else
|
||||
echo "Chain not deleted"
|
||||
fi
|
||||
|
||||
|
||||
gbp group-update fw_lb-provider --provided-policy-rule-sets "fw_lb-webredirect-ruleset=None" --network-service-policy fw_lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw_lb-provider 600
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw_lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "1" ]; then
|
||||
echo "Chain created"
|
||||
|
@ -20,6 +20,7 @@ EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
|
||||
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
|
||||
|
||||
source $TOP_DIR/openrc neutron service
|
||||
source $TOP_DIR/exercises/nfp_lib.sh
|
||||
|
||||
create_gbp_resources() {
|
||||
gbp servicechain-node-create --service-profile base_mode_fw_vm --config 'custom_json:{"mimetype": "config/custom+json","rules": [{"action": "log", "name": "tcp", "service": "tcp/80"}, {"action": "log", "name": "tcp", "service": "tcp/8080"}, {"action": "accept", "name": "tcp", "service": "tcp/22"}, {"action": "accept", "name": "icmp", "service": "icmp"}]}' FWNODE
|
||||
@ -36,6 +37,8 @@ create_gbp_resources() {
|
||||
gbp policy-rule-set-create --policy-rules "fw-web-redirect-rule fw-web-allow-rule-tcp fw-web-allow-rule-udp fw-web-allow-rule-icmp" fw-webredirect-ruleset
|
||||
gbp group-create fw-consumer --consumed-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
gbp group-create fw-provider --provided-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw-provider 600
|
||||
}
|
||||
|
||||
delete_gbp_resources() {
|
||||
@ -53,6 +56,8 @@ delete_gbp_resources() {
|
||||
gbp policy-action-delete allow-to-fw
|
||||
gbp servicechain-spec-delete fw-chainspec
|
||||
gbp servicechain-node-delete FWNODE
|
||||
# Added sleep of 300 secs to complete delete operation
|
||||
sleep 300
|
||||
}
|
||||
|
||||
validate_gbp_resources() {
|
||||
@ -102,6 +107,8 @@ update_gbp_resources() {
|
||||
#fi
|
||||
|
||||
gbp group-delete fw-provider
|
||||
# Added sleep of 300 secs to complete delete operation
|
||||
sleep 300
|
||||
gbp group-delete fw-consumer
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "0" ]; then
|
||||
@ -119,8 +126,10 @@ update_gbp_resources() {
|
||||
else
|
||||
echo "Chain not deleted"
|
||||
fi
|
||||
|
||||
|
||||
gbp group-update fw-provider --provided-policy-rule-sets "fw-webredirect-ruleset=None"
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw-provider 600
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "1" ]; then
|
||||
echo "Chain created"
|
||||
|
@ -20,6 +20,7 @@ EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
|
||||
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
|
||||
|
||||
source $TOP_DIR/openrc neutron service
|
||||
source $TOP_DIR/exercises/nfp_lib.sh
|
||||
|
||||
create_gbp_resources() {
|
||||
# E-W insertion
|
||||
@ -33,6 +34,8 @@ create_gbp_resources() {
|
||||
gbp network-service-policy-create --network-service-params type=ip_single,name=vip_ip,value=self_subnet fw_lb_nsp
|
||||
gbp group-create fw_lb-consumer --consumed-policy-rule-sets "fw_lb-webredirect-ruleset=None"
|
||||
gbp group-create fw_lb-provider --provided-policy-rule-sets "fw_lb-webredirect-ruleset=None" --network-service-policy fw_lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw_lb-provider 600
|
||||
}
|
||||
|
||||
delete_gbp_resources() {
|
||||
@ -46,6 +49,8 @@ delete_gbp_resources() {
|
||||
gbp servicechain-spec-delete fw_lb_chainspec
|
||||
gbp servicechain-node-delete FW_LB-LBNODE
|
||||
gbp servicechain-node-delete FW_LB-FWNODE
|
||||
# Added sleep of 300 secs to complete delete operation
|
||||
sleep 300
|
||||
}
|
||||
|
||||
validate_gbp_resources() {
|
||||
@ -109,7 +114,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group fw_lb-provider provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -118,7 +124,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group fw_lb-provider provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "2" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -127,7 +134,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
@ -136,7 +144,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status fw_lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "0" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
@ -157,6 +166,8 @@ update_gbp_resources() {
|
||||
#fi
|
||||
|
||||
gbp group-delete fw_lb-provider
|
||||
# Added sleep of 300 secs to complete delete operation
|
||||
sleep 300
|
||||
gbp group-delete fw_lb-consumer
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw_lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "0" ]; then
|
||||
@ -174,8 +185,10 @@ update_gbp_resources() {
|
||||
else
|
||||
echo "Chain not deleted"
|
||||
fi
|
||||
|
||||
|
||||
gbp group-update fw_lb-provider --provided-policy-rule-sets "fw_lb-webredirect-ruleset=None" --network-service-policy fw_lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status fw_lb-provider 600
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep fw_lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "1" ]; then
|
||||
echo "Chain created"
|
||||
|
@ -21,6 +21,7 @@ EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
|
||||
TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
|
||||
|
||||
source $TOP_DIR/openrc neutron service
|
||||
source $TOP_DIR/exercises/nfp_lib.sh
|
||||
|
||||
create_gbp_resources() {
|
||||
# E-W insertion
|
||||
@ -33,6 +34,8 @@ create_gbp_resources() {
|
||||
gbp network-service-policy-create --network-service-params type=ip_single,name=vip_ip,value=self_subnet lb_nsp
|
||||
gbp group-create lb-consumer --consumed-policy-rule-sets "lb-webredirect-ruleset=None"
|
||||
gbp group-create lb-provider --provided-policy-rule-sets "lb-webredirect-ruleset=None" --network-service-policy lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status lb-provider 600
|
||||
}
|
||||
|
||||
delete_gbp_resources() {
|
||||
@ -45,6 +48,8 @@ delete_gbp_resources() {
|
||||
gbp policy-action-delete redirect-to-lb
|
||||
gbp servicechain-spec-delete lb_chainspec
|
||||
gbp servicechain-node-delete LB-NODE
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
}
|
||||
|
||||
validate_gbp_resources() {
|
||||
@ -79,7 +84,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group lb-provider provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -88,7 +94,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-create --policy-target-group lb-provider provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "2" ]; then
|
||||
echo "LB Member resource created"
|
||||
@ -97,7 +104,8 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt1
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "1" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
@ -106,18 +114,21 @@ validate_loadbalancer_resources() {
|
||||
fi
|
||||
|
||||
gbp policy-target-delete provider_pt2
|
||||
sleep 5
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 300 secs.
|
||||
check_group_status lb-provider 300
|
||||
LBMemberCount=`neutron lbaas-member-list $LBPoolUUID -f value | wc -l`
|
||||
if [ "$LBMemberCount" -eq "0" ]; then
|
||||
echo "LB Member resource deleted"
|
||||
else
|
||||
echo "LB Member resource not deleted"
|
||||
fi
|
||||
|
||||
|
||||
}
|
||||
|
||||
update_gbp_resources() {
|
||||
gbp group-delete lb-provider
|
||||
# Added sleep 60 sec to complete delete operation
|
||||
sleep 60
|
||||
gbp group-delete lb-consumer
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "0" ]; then
|
||||
@ -135,8 +146,10 @@ update_gbp_resources() {
|
||||
else
|
||||
echo "Chain not deleted"
|
||||
fi
|
||||
|
||||
|
||||
gbp group-update lb-provider --provided-policy-rule-sets "lb-webredirect-ruleset=None" --network-service-policy lb_nsp
|
||||
# Poll for group status till it becomes ACTIVE/ERROR. Polling timeout is 600 secs.
|
||||
check_group_status lb-provider 600
|
||||
ServiceChainInstanceCount=`gbp sci-list -f value | grep lb-provider | wc -l`
|
||||
if [ "$ServiceChainInstanceCount" -eq "1" ]; then
|
||||
echo "Chain created"
|
||||
|
20
gbpservice/tests/contrib/devstack/exercises-nfp/nfp_lib.sh
Executable file
20
gbpservice/tests/contrib/devstack/exercises-nfp/nfp_lib.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
check_group_status(){
|
||||
ptg_name=$1
|
||||
timeout=$2
|
||||
curr_time=0
|
||||
while [ $curr_time -lt $timeout ];
|
||||
do
|
||||
ptg_status=$(gbp group-show $ptg_name | grep -w 'status' | awk '{print $4}')
|
||||
if [ 'ACTIVE' == $ptg_status ];then
|
||||
echo "group $ptg_name becomes ACTIVE after $curr_time secs"
|
||||
break
|
||||
elif [ 'ERROR' == $ptg_status ];then
|
||||
echo "group $ptg_name went to ERROR state after $curr_time secs"
|
||||
break
|
||||
fi
|
||||
sleep 5
|
||||
curr_time=$((curr_time + 5))
|
||||
done
|
||||
}
|
Loading…
Reference in New Issue
Block a user