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:
parent
2c06965290
commit
deda419288
|
@ -20,8 +20,15 @@ import platform
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon.utils.memoized import memoized
|
from horizon.utils.memoized import memoized
|
||||||
from oslo_config import cfg
|
|
||||||
|
try:
|
||||||
import oslo_messaging as messaging
|
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__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -51,39 +58,18 @@ class DFAClient(object):
|
||||||
|
|
||||||
return self.clnt
|
return self.clnt
|
||||||
|
|
||||||
def do_precreate_network(self, network):
|
def associate_profile_with_network(self, network):
|
||||||
'''Precreate network on current version of Fabric Enabler'''
|
|
||||||
|
|
||||||
context = {}
|
context = {}
|
||||||
args = json.dumps(network)
|
args = json.dumps(network)
|
||||||
try:
|
try:
|
||||||
resp = self.clnt.call(context, 'precreate_network', msg=args)
|
resp = self.clnt.call(context,
|
||||||
if not resp:
|
'associate_profile_with_network',
|
||||||
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)
|
msg=args)
|
||||||
if not resp:
|
|
||||||
raise exceptions.NotAvailable("Project %(id)s not present in "
|
|
||||||
"fabric enabler" %
|
|
||||||
{'id': network.get('tenant_id')})
|
|
||||||
return resp
|
return resp
|
||||||
except (messaging.MessagingException, messaging.RemoteError,
|
except (messaging.MessagingException, messaging.RemoteError,
|
||||||
messaging.MessagingTimeout):
|
messaging.MessagingTimeout):
|
||||||
LOG.error("RPC: Request to delete precreated network failed.")
|
LOG.error("RPC: Request to associate profile with network"
|
||||||
|
" failed.")
|
||||||
raise exceptions.NotAvailable("RPC to Fabric Enabler failed")
|
raise exceptions.NotAvailable("RPC to Fabric Enabler failed")
|
||||||
|
|
||||||
def get_config_profiles_detail(self):
|
def get_config_profiles_detail(self):
|
||||||
|
|
|
@ -30,44 +30,31 @@ class DFAClientTestCase(test.BaseAdminViewTests):
|
||||||
with mock.patch('horizon_cisco_ui.cisco.dfa.dfa_client.ConfigParser.ConfigParser'), \
|
with mock.patch('horizon_cisco_ui.cisco.dfa.dfa_client.ConfigParser.ConfigParser'), \
|
||||||
mock.patch('oslo_messaging.RPCClient'), \
|
mock.patch('oslo_messaging.RPCClient'), \
|
||||||
mock.patch('oslo_messaging.get_transport'):
|
mock.patch('oslo_messaging.get_transport'):
|
||||||
self.DFAClient = dfa_client.DFAClient()
|
self.client = dfa_client.DFAClient()
|
||||||
|
|
||||||
def test_do_precreate_network(self):
|
def test_do_associate_profile_with_network(self):
|
||||||
network = dict(tenant_id=1,
|
network = dict(id='1125-as45-afg5f-3457',
|
||||||
nwk_name='net1',
|
cfgp='defaultNetworkL2Profile',
|
||||||
subnet='10.0.0.0/24',
|
name='net1',
|
||||||
cfgp='defaultNetworkL2Profile')
|
tenant_id=1)
|
||||||
|
|
||||||
message = json.dumps(network)
|
message = json.dumps(network)
|
||||||
with mock.patch.object(self.DFAClient.clnt, 'call') as mock_call:
|
with mock.patch.object(self.client.clnt, 'call') as mock_call:
|
||||||
self.DFAClient.do_precreate_network(network)
|
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):
|
def test_associate_profile_with_network_rpc_exception(self):
|
||||||
network = dict(tenant_id=1,
|
network = dict(id='1125-as45-afg5f-3457',
|
||||||
nwk_name='net1',
|
cfgp='defaultNetworkL2Profile',
|
||||||
subnet='10.0.0.0/24',
|
name='net1',
|
||||||
cfgp='defaultNetworkL2Profile')
|
tenant_id=1)
|
||||||
|
|
||||||
with mock.patch.object(self.DFAClient.clnt, 'call',
|
with mock.patch.object(self.client.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',
|
|
||||||
side_effect=dfa_client.messaging.MessagingException), \
|
side_effect=dfa_client.messaging.MessagingException), \
|
||||||
self.assertRaises(dfa_client.exceptions.NotAvailable) as cm:
|
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',
|
self.assertEqual('RPC to Fabric Enabler failed',
|
||||||
str(cm.exception))
|
str(cm.exception))
|
||||||
|
|
|
@ -19,7 +19,6 @@ from horizon import forms
|
||||||
from horizon import workflows
|
from horizon import workflows
|
||||||
from horizon_cisco_ui.cisco.dfa import dfa_client
|
from horizon_cisco_ui.cisco.dfa import dfa_client
|
||||||
|
|
||||||
from openstack_dashboard import api
|
|
||||||
from openstack_dashboard.dashboards.project.networks import \
|
from openstack_dashboard.dashboards.project.networks import \
|
||||||
workflows as upstream_networks_workflows
|
workflows as upstream_networks_workflows
|
||||||
|
|
||||||
|
@ -27,21 +26,20 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DFAConfigProfileAction(workflows.Action):
|
class DFAConfigProfileAction(workflows.Action):
|
||||||
cfg_profile = forms.ChoiceField(label=_("Config Profile"), required=False,
|
cfg_profile = forms.ChoiceField(label=_("Network Profile"), required=False,
|
||||||
help_text=_("Select Config Profile to "
|
help_text=_("Select network profile to "
|
||||||
"associate with Network."))
|
"associate with Network."))
|
||||||
|
|
||||||
def __init__(self, request, *args, **kwargs):
|
class Meta(object):
|
||||||
super(DFAConfigProfileAction, self).__init__(request, *args, **kwargs)
|
name = _("Programmable Fabric")
|
||||||
self.fields['cfg_profile'].choices = \
|
|
||||||
self.get_config_profile_choices(request)
|
|
||||||
|
|
||||||
def get_config_profile_choices(self, request):
|
''' This function call get_config_profiles_detail api of DFA Client
|
||||||
profile_choices = [('', _("Select a config profile"))]
|
which fetches the profile list from Fabric Enabler using RPC,
|
||||||
for profile in self._get_cfg_profiles(request):
|
and return profile names filtered by the profile Sub Type
|
||||||
profile_choices.append((profile, profile))
|
|
||||||
return profile_choices
|
|
||||||
|
|
||||||
|
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):
|
def _get_cfg_profiles(self, request):
|
||||||
profiles = []
|
profiles = []
|
||||||
try:
|
try:
|
||||||
|
@ -49,25 +47,33 @@ class DFAConfigProfileAction(workflows.Action):
|
||||||
if not bool(dfaclient.__dict__):
|
if not bool(dfaclient.__dict__):
|
||||||
return profiles
|
return profiles
|
||||||
cfgplist = dfaclient.get_config_profiles_detail()
|
cfgplist = dfaclient.get_config_profiles_detail()
|
||||||
profiles = [profile for cfgp in cfgplist
|
profiles = [q for p in cfgplist
|
||||||
if (cfgp.get('profileSubType') == 'network:universal')
|
if (p.get('profileSubType') == 'network:universal')
|
||||||
for profile in [cfgp.get('profileName')]]
|
for q in [p.get('profileName')]]
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
exceptions.handle(request, exc.message)
|
exceptions.handle(request, exc.message)
|
||||||
return profiles
|
return profiles
|
||||||
|
|
||||||
class Meta(object):
|
def populate_cfg_profile_choices(self, request, context):
|
||||||
name = _("Programmable Fabric")
|
profile_choices = [('', _("Select a config profile"))]
|
||||||
help_text = _("Select Config Profile from the list "
|
for profile in self._get_cfg_profiles(request):
|
||||||
"to associate with your network.")
|
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):
|
class DFAConfigProfileInfo(workflows.Step):
|
||||||
action_class = DFAConfigProfileAction
|
action_class = DFAConfigProfileAction
|
||||||
|
|
||||||
def contribute(self, data, context):
|
def contribute(self, data, context):
|
||||||
for key, value in data.items():
|
for k, v in data.items():
|
||||||
context[key] = value
|
context[k] = v
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,71 +83,18 @@ class DFACreateNetwork(upstream_networks_workflows.CreateNetwork):
|
||||||
upstream_networks_workflows.CreateSubnetDetail,
|
upstream_networks_workflows.CreateSubnetDetail,
|
||||||
DFAConfigProfileInfo)
|
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
|
@staticmethod
|
||||||
def handle(self, request, data):
|
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)
|
network = self._create_network(request, data)
|
||||||
if not network:
|
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
|
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 we do not need to create a subnet, return here.
|
||||||
if not data['with_subnet']:
|
if not data['with_subnet']:
|
||||||
return True
|
return True
|
||||||
|
@ -150,11 +103,4 @@ class DFACreateNetwork(upstream_networks_workflows.CreateNetwork):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self._delete_network(request, network)
|
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
|
return False
|
||||||
|
|
Loading…
Reference in New Issue