Added new event to asscoiate profile with network

Removed the "precreate_network" logic from "Create Network" workflow
and added a new RPC "associate_profile_with_network" which simplifies
the workflow and take away the dependency from Network and Subnet
workflow

Change-Id: I9518cef3264ddf2e9a5d53172d41534aa88d49b7
This commit is contained in:
chiragtayal 2016-12-01 16:56:04 -08:00
parent 2c06965290
commit deda419288
3 changed files with 73 additions and 154 deletions

View File

@ -20,8 +20,15 @@ import platform
from horizon import exceptions
from horizon.utils.memoized import memoized
from oslo_config import cfg
import oslo_messaging as messaging
try:
import oslo_messaging as messaging
except ImportError:
from oslo import messaging
try:
from oslo_config import cfg
except ImportError:
from oslo.config import cfg
LOG = logging.getLogger(__name__)
@ -51,40 +58,19 @@ class DFAClient(object):
return self.clnt
def do_precreate_network(self, network):
'''Precreate network on current version of Fabric Enabler'''
context = {}
args = json.dumps(network)
try:
resp = self.clnt.call(context, 'precreate_network', msg=args)
if not resp:
raise exceptions.NotAvailable("Project %(id)s not present in "
"fabric enabler" %
{'id': network.get('tenant_id')})
return resp
except (messaging.MessagingException, messaging.RemoteError,
messaging.MessagingTimeout):
LOG.error("RPC: Request to precreate network failed.")
raise exceptions.NotAvailable("RPC to Fabric Enabler failed")
def do_delete_precreate_network(self, network):
'''Delete precreate network on current version of Fabric Enabler'''
context = {}
args = json.dumps(network)
try:
resp = self.clnt.call(context, 'delete_precreate_network',
msg=args)
if not resp:
raise exceptions.NotAvailable("Project %(id)s not present in "
"fabric enabler" %
{'id': network.get('tenant_id')})
return resp
except (messaging.MessagingException, messaging.RemoteError,
messaging.MessagingTimeout):
LOG.error("RPC: Request to delete precreated network failed.")
raise exceptions.NotAvailable("RPC to Fabric Enabler failed")
def associate_profile_with_network(self, network):
context = {}
args = json.dumps(network)
try:
resp = self.clnt.call(context,
'associate_profile_with_network',
msg=args)
return resp
except (messaging.MessagingException, messaging.RemoteError,
messaging.MessagingTimeout):
LOG.error("RPC: Request to associate profile with network"
" failed.")
raise exceptions.NotAvailable("RPC to Fabric Enabler failed")
def get_config_profiles_detail(self):
'''Get all config Profiles details from the Fabric Enabler'''

View File

@ -30,44 +30,31 @@ class DFAClientTestCase(test.BaseAdminViewTests):
with mock.patch('horizon_cisco_ui.cisco.dfa.dfa_client.ConfigParser.ConfigParser'), \
mock.patch('oslo_messaging.RPCClient'), \
mock.patch('oslo_messaging.get_transport'):
self.DFAClient = dfa_client.DFAClient()
self.client = dfa_client.DFAClient()
def test_do_precreate_network(self):
network = dict(tenant_id=1,
nwk_name='net1',
subnet='10.0.0.0/24',
cfgp='defaultNetworkL2Profile')
def test_do_associate_profile_with_network(self):
network = dict(id='1125-as45-afg5f-3457',
cfgp='defaultNetworkL2Profile',
name='net1',
tenant_id=1)
message = json.dumps(network)
with mock.patch.object(self.DFAClient.clnt, 'call') as mock_call:
self.DFAClient.do_precreate_network(network)
with mock.patch.object(self.client.clnt, 'call') as mock_call:
self.client.associate_profile_with_network(network)
mock_call.assert_called_with({}, 'precreate_network', msg=message)
mock_call.assert_called_with({}, 'associate_profile_with_network',
msg=message)
def test_do_precreate_network_not_available_exception(self):
network = dict(tenant_id=1,
nwk_name='net1',
subnet='10.0.0.0/24',
cfgp='defaultNetworkL2Profile')
def test_associate_profile_with_network_rpc_exception(self):
network = dict(id='1125-as45-afg5f-3457',
cfgp='defaultNetworkL2Profile',
name='net1',
tenant_id=1)
with mock.patch.object(self.DFAClient.clnt, 'call',
return_value=False), \
self.assertRaises(dfa_client.exceptions.NotAvailable) as cm:
self.DFAClient.do_precreate_network(network)
self.assertEqual('Project 1 not present in fabric enabler',
str(cm.exception))
def test_do_precreate_network_rpc_exception(self):
network = dict(tenant_id=1,
nwk_name='net1',
subnet='10.0.0.0/24',
cfgp='defaultNetworkL2Profile')
with mock.patch.object(self.DFAClient.clnt, 'call',
with mock.patch.object(self.client.clnt, 'call',
side_effect=dfa_client.messaging.MessagingException), \
self.assertRaises(dfa_client.exceptions.NotAvailable) as cm:
self.DFAClient.do_precreate_network(network)
self.client.associate_profile_with_network(network)
self.assertEqual('RPC to Fabric Enabler failed',
str(cm.exception))

View File

@ -19,7 +19,6 @@ from horizon import forms
from horizon import workflows
from horizon_cisco_ui.cisco.dfa import dfa_client
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.networks import \
workflows as upstream_networks_workflows
@ -27,21 +26,20 @@ LOG = logging.getLogger(__name__)
class DFAConfigProfileAction(workflows.Action):
cfg_profile = forms.ChoiceField(label=_("Config Profile"), required=False,
help_text=_("Select Config Profile to "
cfg_profile = forms.ChoiceField(label=_("Network Profile"), required=False,
help_text=_("Select network profile to "
"associate with Network."))
def __init__(self, request, *args, **kwargs):
super(DFAConfigProfileAction, self).__init__(request, *args, **kwargs)
self.fields['cfg_profile'].choices = \
self.get_config_profile_choices(request)
class Meta(object):
name = _("Programmable Fabric")
def get_config_profile_choices(self, request):
profile_choices = [('', _("Select a config profile"))]
for profile in self._get_cfg_profiles(request):
profile_choices.append((profile, profile))
return profile_choices
''' This function call get_config_profiles_detail api of DFA Client
which fetches the profile list from Fabric Enabler using RPC,
and return profile names filtered by the profile Sub Type
p is an iterator over profile list that we got from the API
q is a filtered list of profileNames based on the condition
'''
def _get_cfg_profiles(self, request):
profiles = []
try:
@ -49,25 +47,33 @@ class DFAConfigProfileAction(workflows.Action):
if not bool(dfaclient.__dict__):
return profiles
cfgplist = dfaclient.get_config_profiles_detail()
profiles = [profile for cfgp in cfgplist
if (cfgp.get('profileSubType') == 'network:universal')
for profile in [cfgp.get('profileName')]]
profiles = [q for p in cfgplist
if (p.get('profileSubType') == 'network:universal')
for q in [p.get('profileName')]]
except Exception as exc:
exceptions.handle(request, exc.message)
return profiles
class Meta(object):
name = _("Programmable Fabric")
help_text = _("Select Config Profile from the list "
"to associate with your network.")
def populate_cfg_profile_choices(self, request, context):
profile_choices = [('', _("Select a config profile"))]
for profile in self._get_cfg_profiles(request):
profile_choices.append((profile, profile))
return profile_choices
def get_help_text(self, extra_context=None):
text = ("Network Profile:"
" An autoconfiguration template consisting of collection of"
" commands which instantiates day-1 tenant-related"
" configurations on CISCO Nexus switches.")
return text
class DFAConfigProfileInfo(workflows.Step):
action_class = DFAConfigProfileAction
def contribute(self, data, context):
for key, value in data.items():
context[key] = value
for k, v in data.items():
context[k] = v
return context
@ -77,71 +83,18 @@ class DFACreateNetwork(upstream_networks_workflows.CreateNetwork):
upstream_networks_workflows.CreateSubnetDetail,
DFAConfigProfileInfo)
@staticmethod
def _create_network(self, request, data):
try:
params = {'name': data['net_name'],
'admin_state_up': (data['admin_state'] == 'True'),
'shared': data['shared']}
if api.neutron.is_port_profiles_supported():
params['net_profile_id'] = data['net_profile_id']
network = api.neutron.network_create(request, **params)
self.context['net_id'] = network.id
msg = (_('Network "%s" was successfully created.') %
network.name_or_id)
LOG.debug(msg)
return network
except Exception as e:
msg = (_('Failed to create network "%(network)s": %(reason)s') %
{"network": data['net_name'], "reason": e})
LOG.info(msg)
# Delete Precreated Network
try:
precreate_network = dict(tenant_id=request.user.project_id,
nwk_name=data['net_name'],
subnet=data['cidr'],
cfgp=data['cfg_profile'])
dfaclient = dfa_client.DFAClient()
if not bool(dfaclient.__dict__):
return False
dfaclient.do_delete_precreate_network(precreate_network)
except Exception as exc:
LOG.error('Unable to delete precreated Network')
exceptions.handle(self.request, exc.message)
redirect = self.get_failure_url()
exceptions.handle(request, msg, redirect=redirect)
return False
@staticmethod
def handle(self, request, data):
precreate_flag = False
'''Pre-create network in enabler'''
precreate_network = dict(tenant_id=request.user.project_id,
nwk_name=data['net_name'],
subnet=data['cidr'],
cfgp=data['cfg_profile'])
if data['cfg_profile']:
dfaclient = dfa_client.DFAClient()
if bool(dfaclient.__dict__):
try:
precreate_flag = dfaclient.do_precreate_network(
precreate_network)
except Exception as exc:
LOG.error('Unable to do precreate Network')
exceptions.handle(self.request, exc.message)
return False
network = self._create_network(request, data)
if not network:
if precreate_flag:
# do precreate delete
try:
dfaclient.do_delete_precreate_network(precreate_network)
precreate_flag = False
except Exception as exc:
LOG.error('Unable to delete precreatedd Network')
exceptions.handle(self.request, exc.message)
return False
if data['cfg_profile']:
dfaclient = dfa_client.DFAClient()
associate_data = {'id': network['id'],
'cfgp': data['cfg_profile'],
'name': network['name'],
'tenant_id': request.user.project_id}
dfaclient.associate_profile_with_network(associate_data)
# If we do not need to create a subnet, return here.
if not data['with_subnet']:
return True
@ -150,11 +103,4 @@ class DFACreateNetwork(upstream_networks_workflows.CreateNetwork):
return True
else:
self._delete_network(request, network)
if precreate_flag:
# do precreate delete
try:
dfaclient.do_delete_precreate_network(precreate_network)
except Exception as exc:
LOG.error('Unable to delete precreated Network')
exceptions.handle(self.request, exc.message)
return False