Create DataNetworks modelling in System Configuration

Introduce stx-gui updates to enable DataNetwork modelling of the
physical data network in sysinv.  This is part of the Story to
"Move neutron provider network modelling to system configuration".

This is an initial update to enable Interfaces, Data Networks and
Data Network Topology panels.

Pending Stein spec support for network-segment-range-mangement,
the following GUI features are not currently supported:
    Segmentation Ranges
    Tenant Networks

The following GUI panels are updated:
    Host Inventory - Interfaces
    Data Networks (<oamip> /admin/datanets; previously /admin/providernets)
    Data Network Topology

Tests Performed:
    Data Network create, modify for network_type flat, vlan.
        vxlan excluded in this GUI commit.
    Data Network delete, modify
    Data Network Topology - basic navigation to panel
    Interface Profile create and apply
    Sanity

Story: 2004455
Task: 28325

Depends-On: https://review.openstack.org/#/c/631701/
Change-Id: I46db5b5d47a9920f21db0521a8f5fbe4213b8af3
Signed-off-by: John Kung <john.kung@windriver.com>
This commit is contained in:
John Kung 2019-01-24 09:49:31 -05:00
parent 8569c522fc
commit 2c4f8a48a4
51 changed files with 463 additions and 470 deletions

View File

@ -1,2 +1,2 @@
SRC_DIR="starlingx-dashboard" SRC_DIR="starlingx-dashboard"
TIS_PATCH_VER=24 TIS_PATCH_VER=25

View File

@ -1935,7 +1935,7 @@ class Interface(base.APIResourceWrapper):
_attrs = ['id', 'uuid', 'ifname', 'ifclass', 'iftype', 'imtu', 'imac', _attrs = ['id', 'uuid', 'ifname', 'ifclass', 'iftype', 'imtu', 'imac',
'networktype', 'networks', 'aemode', 'txhashpolicy', 'vlan_id', 'networktype', 'networks', 'aemode', 'txhashpolicy', 'vlan_id',
'uses', 'used_by', 'ihost_uuid', 'providernetworks', 'uses', 'used_by', 'ihost_uuid', 'datanetworks',
'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool', 'ipv4_mode', 'ipv6_mode', 'ipv4_pool', 'ipv6_pool',
'sriov_numvfs'] 'sriov_numvfs']
@ -1944,6 +1944,10 @@ class Interface(base.APIResourceWrapper):
if not self.ifname: if not self.ifname:
self.ifname = '(' + str(self.uuid)[-8:] + ')' self.ifname = '(' + str(self.uuid)[-8:] + ')'
@property
def datanetworks_csv(self):
return ",".join(self.datanetworks)
def host_interface_list(request, host_id): def host_interface_list(request, host_id):
interfaces = cgtsclient(request).iinterface.list(host_id) interfaces = cgtsclient(request).iinterface.list(host_id)
@ -2578,3 +2582,64 @@ def is_system_k8s_aio(request):
def is_host_with_storage(request, host_id): def is_host_with_storage(request, host_id):
host = host_get(request, host_id) host = host_get(request, host_id)
return 'storage' in host.subfunctions or is_system_k8s_aio(request) return 'storage' in host.subfunctions or is_system_k8s_aio(request)
class DataNetwork(base.APIResourceWrapper):
"""..."""
_attrs = ['id', 'uuid', 'network_type', 'name', 'mtu', 'description',
'multicast_group', 'port_num', 'ttl', 'mode']
def __init__(self, apiresource):
super(DataNetwork, self).__init__(apiresource)
DATANETWORK_TYPE_FLAT = "flat"
DATANETWORK_TYPE_VLAN = "vlan"
DATANETWORK_TYPE_VXLAN = "vxlan"
data_network_type_choices_list = [
(DATANETWORK_TYPE_FLAT, DATANETWORK_TYPE_FLAT),
(DATANETWORK_TYPE_VLAN, DATANETWORK_TYPE_VLAN),
(DATANETWORK_TYPE_VXLAN, DATANETWORK_TYPE_VXLAN),
]
def data_network_type_choices():
return data_network_type_choices_list
def data_network_create(request, **kwargs):
LOG.info("data_network_create(): kwargs=%s", kwargs)
datanet = cgtsclient(request).datanetwork.create(**kwargs)
return DataNetwork(datanet)
def data_network_list(request):
datanets = cgtsclient(request).datanetwork.list()
return [DataNetwork(n) for n in datanets]
def data_network_get(request, datanet_id):
datanet = cgtsclient(request).datanetwork.get(datanet_id)
if not datanet:
raise ValueError('No match found for datanet_id "%s".' % datanet_id)
return DataNetwork(datanet)
def data_network_modify(request, datanet_id, **kwargs):
LOG.info("data_network_modify(): datanet_id,=%s, kwargs=%s",
datanet_id, kwargs)
patch = []
for key, value in kwargs.items():
patch.append(dict(path='/' + key, value=value, op='replace'))
datanet = cgtsclient(request).datanetwork.update(datanet_id, patch)
if not datanet:
raise ValueError('No match found for datanet_id "%s".' % datanet_id)
return DataNetwork(datanet)
def data_network_delete(request, datanet_id):
LOG.info("data_network_delete(): datanet_id=%s", datanet_id)
return cgtsclient(request).datanetwork.delete(datanet_id)

View File

@ -0,0 +1,147 @@
# Copyright 2012 NEC Corporation
#
# 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.
#
# Copyright (c) 2013-2019 Wind River Systems, Inc.
#
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _ # noqa
from cgtsclient import exc as sysinv_exceptions
from horizon import exceptions
from horizon import forms
from horizon import messages
from starlingx_dashboard import api as stx_api
LOG = logging.getLogger(__name__)
class CreateDataNetwork(forms.SelfHandlingForm):
name = forms.CharField(max_length=255,
label=_("Name"),
required=True)
description = forms.CharField(max_length=255,
label=_("Description"),
required=False)
network_type = forms.ChoiceField(label=_("Type"),
required=True)
mtu = forms.IntegerField(
label=_("MTU"),
required=True,
initial=1500,
min_value=576,
max_value=9216,
help_text=(
_("Specifies the maximum MTU value of any associated tenant "
"network. Worker node data interface MTU values must be large "
"enough to support the tenant MTU plus any additional provider "
"encapsulation headers. For example, VXLAN provider MTU of "
"1500 requires a minimum data interface MTU of 1574 bytes (1600 "
"bytes is recommended.")))
@classmethod
def _instantiate(cls, request, *args, **kwargs):
return cls(request, *args, **kwargs)
def __init__(self, request, *args, **kwargs):
super(CreateDataNetwork, self).__init__(request, *args, **kwargs)
datanet_type_choices = [('', _("Select a network type"))]
datanet_choices_list = stx_api.sysinv.data_network_type_choices()
for datanet_choices_tuple in datanet_choices_list:
datanet_type_choices.append(datanet_choices_tuple)
self.fields['network_type'].choices = datanet_type_choices
def clean(self):
cleaned_data = super(CreateDataNetwork, self).clean()
if len(cleaned_data['name'].lstrip()) == 0:
raise forms.ValidationError('invalid data network name')
return cleaned_data
def handle(self, request, data):
try:
params = {'name': data['name'],
'network_type': data['network_type'],
'description': data['description'],
'mtu': data['mtu']}
network = stx_api.sysinv.data_network_create(request,
**params)
msg = (_('Data network %s was successfully created.') %
data['name'])
LOG.info(msg)
messages.success(request, msg)
return network
except sysinv_exceptions.CgtsclientException as e:
redirect = reverse('horizon:admin:datanets:index')
exceptions.handle(request, str(e), redirect=redirect)
except Exception:
redirect = reverse('horizon:admin:datanets:index')
msg = _('Failed to create data network %s') % data['name']
exceptions.handle(request, msg, redirect=redirect)
class UpdateDataNetwork(forms.SelfHandlingForm):
name = forms.CharField(label=_("Name"), required=False,
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
network_type = forms.CharField(label=_("Type"), required=False,
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
id = forms.CharField(widget=forms.HiddenInput)
# Mutable fields
description = forms.CharField(label=_("Description"), required=False)
mtu = forms.IntegerField(label=_("MTU"),
required=True,
initial=1500,
min_value=576,
max_value=9216,
help_text=(_("Specifies the minimum interface "
"MTU required to support this "
"data network ")))
failure_url = 'horizon:admin:datanets:index'
def handle(self, request, data):
try:
if not data['description']:
data['description'] = '_'
params = {'description': data['description'],
'mtu': data['mtu']}
providernet = stx_api.sysinv.data_network_modify(
request, data['id'], **params)
msg = (_('Data network %s was successfully updated.') %
data['name'])
LOG.info(msg)
messages.success(request, msg)
return providernet
except sysinv_exceptions.CgtsclientException as e:
msg = _('Failed to update data network %s') % data['name']
LOG.info(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, str(e), redirect=redirect)
except Exception:
msg = _('Failed to update data network %s') % data['name']
LOG.info(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
@ -146,7 +146,7 @@ class CreateProviderNetworkRange(forms.SelfHandlingForm):
return providernet_range return providernet_range
except neutron_exceptions.NeutronClientException as e: except neutron_exceptions.NeutronClientException as e:
LOG.info(str(e)) LOG.info(str(e))
redirect = reverse('horizon:admin:providernets:providernets:' redirect = reverse('horizon:admin:datanets:datanets:'
'detail', 'detail',
args=(data['providernet_id'],)) args=(data['providernet_id'],))
exceptions.handle(request, str(e), redirect=redirect) exceptions.handle(request, str(e), redirect=redirect)
@ -155,7 +155,7 @@ class CreateProviderNetworkRange(forms.SelfHandlingForm):
' network range for network %s') \ ' network range for network %s') \
% data['providernet_id'] % data['providernet_id']
LOG.info(msg) LOG.info(msg)
redirect = reverse('horizon:admin:providernets:providernets:' redirect = reverse('horizon:admin:datanets:datanets:'
'detail', 'detail',
args=(data['providernet_id'],)) args=(data['providernet_id'],))
exceptions.handle(request, msg, redirect=redirect) exceptions.handle(request, msg, redirect=redirect)
@ -170,7 +170,7 @@ class CreateProviderNetworkRange(forms.SelfHandlingForm):
class UpdateProviderNetworkRange(forms.SelfHandlingForm): class UpdateProviderNetworkRange(forms.SelfHandlingForm):
failure_url = 'horizon:admin:providernets:providernets:detail' failure_url = 'horizon:admin:datanets:datanets:detail'
providernet_id = forms.CharField(widget=forms.HiddenInput()) providernet_id = forms.CharField(widget=forms.HiddenInput())
providernet_range_id = forms.CharField(widget=forms.HiddenInput()) providernet_range_id = forms.CharField(widget=forms.HiddenInput())
name = forms.CharField(max_length=255, name = forms.CharField(max_length=255,
@ -237,7 +237,7 @@ class UpdateProviderNetworkRange(forms.SelfHandlingForm):
return providernet_range return providernet_range
except neutron_exceptions.NeutronClientException as e: except neutron_exceptions.NeutronClientException as e:
LOG.info(str(e)) LOG.info(str(e))
redirect = reverse('horizon:admin:providernets:providernets:' redirect = reverse('horizon:admin:datanets:datanets:'
'detail', 'detail',
args=(data['providernet_id'],)) args=(data['providernet_id'],))
exceptions.handle(request, str(e), redirect=redirect) exceptions.handle(request, str(e), redirect=redirect)

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
@ -52,7 +52,7 @@ class DeleteProviderNetworkRange(tables.DeleteAction):
def get_redirect_url(self): def get_redirect_url(self):
providernet_id = self.table.kwargs['providernet_id'] providernet_id = self.table.kwargs['providernet_id']
return reverse('horizon:admin:providernets:providernets:detail', return reverse('horizon:admin:datanets:datanets:detail',
args=(providernet_id,)) args=(providernet_id,))
def delete(self, request, obj_id): def delete(self, request, obj_id):
@ -72,7 +72,7 @@ class DeleteProviderNetworkRange(tables.DeleteAction):
class CreateProviderNetworkRange(tables.LinkAction): class CreateProviderNetworkRange(tables.LinkAction):
name = "create" name = "create"
verbose_name = _("Create Range") verbose_name = _("Create Range")
url = "horizon:admin:providernets:providernets:createrange" url = "horizon:admin:datanets:datanets:createrange"
classes = ("ajax-modal", "btn-create") classes = ("ajax-modal", "btn-create")
def get_link_url(self, datum=None): def get_link_url(self, datum=None):
@ -80,16 +80,14 @@ class CreateProviderNetworkRange(tables.LinkAction):
return reverse(self.url, args=(providernet_id,)) return reverse(self.url, args=(providernet_id,))
def allowed(self, request, datum=None): def allowed(self, request, datum=None):
providernet = self.table.kwargs.get('providernet') # TODO(datanetworks): depends on spec network-segment-range-management
if providernet: return False
return (providernet.type not in ('flat'))
return True
class EditProviderNetworkRange(tables.LinkAction): class EditProviderNetworkRange(tables.LinkAction):
name = "update" name = "update"
verbose_name = _("Edit Range") verbose_name = _("Edit Range")
url = "horizon:admin:providernets:providernets:editrange" url = "horizon:admin:datanets:datanets:editrange"
classes = ("ajax-modal", "btn-edit") classes = ("ajax-modal", "btn-edit")
def get_link_url(self, providernet_range): def get_link_url(self, providernet_range):
@ -113,7 +111,7 @@ class ProviderNetworkRangeTable(tables.DataTable):
tenant = tables.Column("tenant_name", verbose_name=_("Project")) tenant = tables.Column("tenant_name", verbose_name=_("Project"))
shared = tables.Column("shared", verbose_name=_("Shared"), shared = tables.Column("shared", verbose_name=_("Shared"),
filters=(filters.yesno, filters.capfirst)) filters=(filters.yesno, filters.capfirst))
url = "horizon:admin:providernets:providernets:ranges:detail" url = "horizon:admin:datanets:datanets:ranges:detail"
name = tables.Column("name", verbose_name=_("Name"), link=url) name = tables.Column("name", verbose_name=_("Name"), link=url)
minimum = tables.Column("minimum", verbose_name=_("Minimum")) minimum = tables.Column("minimum", verbose_name=_("Minimum"))
maximum = tables.Column("maximum", verbose_name=_("Maximum")) maximum = tables.Column("maximum", verbose_name=_("Maximum"))

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
from django.utils.translation import ugettext_lazy as _ # noqa from django.utils.translation import ugettext_lazy as _ # noqa
@ -23,7 +23,7 @@ from horizon import tabs
class OverviewTab(tabs.Tab): class OverviewTab(tabs.Tab):
name = _("Overview") name = _("Overview")
slug = "overview" slug = "overview"
template_name = "admin/providernets/providernets/ranges/" \ template_name = "admin/datanets/datanets/ranges/" \
"_detail_overview.html" "_detail_overview.html"
def get_context_data(self, request): def get_context_data(self, request):

View File

@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
from django.conf.urls import url # noqa from django.conf.urls import url # noqa
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import views import views
RANGES = r'^(?P<providernet_range_id>[^/]+)/%s$' RANGES = r'^(?P<providernet_range_id>[^/]+)/%s$'

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
@ -25,17 +25,17 @@ from horizon import tabs
from horizon.utils import memoized from horizon.utils import memoized
from starlingx_dashboard import api as stx_api from starlingx_dashboard import api as stx_api
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import forms as range_forms import forms as range_forms
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import tabs as range_tabs import tabs as range_tabs
class CreateView(forms.ModalFormView): class CreateView(forms.ModalFormView):
form_class = range_forms.CreateProviderNetworkRange form_class = range_forms.CreateProviderNetworkRange
template_name = 'admin/providernets/providernets/ranges/create.html' template_name = 'admin/datanets/datanets/ranges/create.html'
success_url = 'horizon:admin:providernets:providernets:detail' success_url = 'horizon:admin:datanets:datanets:detail'
failure_url = 'horizon:admin:providernets:providernets:detail' failure_url = 'horizon:admin:datanets:datanets:detail'
def get_success_url(self): def get_success_url(self):
return reverse(self.success_url, return reverse(self.success_url,
@ -73,7 +73,7 @@ class CreateView(forms.ModalFormView):
class DetailView(tabs.TabView): class DetailView(tabs.TabView):
tab_group_class = range_tabs.ProviderNetworkRangeDetailTabs tab_group_class = range_tabs.ProviderNetworkRangeDetailTabs
template_name = 'admin/providernets/providernets/ranges/detail.html' template_name = 'admin/datanets/datanets/ranges/detail.html'
page_title = '{{ providernet_range.name }}' page_title = '{{ providernet_range.name }}'
def _get_object(self): def _get_object(self):
@ -85,7 +85,7 @@ class DetailView(tabs.TabView):
self.request, providernet_range_id) self.request, providernet_range_id)
except Exception: except Exception:
redirect = \ redirect = \
reverse("horizon:admin:providernets:providernets:detail", reverse("horizon:admin:datanets:datanets:detail",
args=( args=(
self.kwargs['providernet_id'],)) self.kwargs['providernet_id'],))
msg = _('Unable to retrieve provider network range details') msg = _('Unable to retrieve provider network range details')
@ -99,7 +99,7 @@ class DetailView(tabs.TabView):
pnet_name = self.get_providernet_name(providernet_range.providernet_id) pnet_name = self.get_providernet_name(providernet_range.providernet_id)
breadcrumb = [ breadcrumb = [
(pnet_name, (pnet_name,
reverse('horizon:admin:providernets:providernets:detail', reverse('horizon:admin:datanets:datanets:detail',
args=(providernet_range.providernet_id,))), args=(providernet_range.providernet_id,))),
(_("Segmentation Ranges"), None) (_("Segmentation Ranges"), None)
] ]
@ -128,9 +128,9 @@ class DetailView(tabs.TabView):
class UpdateView(forms.ModalFormView): class UpdateView(forms.ModalFormView):
form_class = range_forms.UpdateProviderNetworkRange form_class = range_forms.UpdateProviderNetworkRange
template_name = 'admin/providernets/providernets/ranges/update.html' template_name = 'admin/datanets/datanets/ranges/update.html'
context_object_name = 'providernet_range' context_object_name = 'providernet_range'
success_url = 'horizon:admin:providernets:providernets:detail' success_url = 'horizon:admin:datanets:datanets:detail'
def get_success_url(self): def get_success_url(self):
value = reverse(self.success_url, value = reverse(self.success_url,
@ -145,7 +145,7 @@ class UpdateView(forms.ModalFormView):
self.request, providernet_range_id) self.request, providernet_range_id)
except Exception: except Exception:
redirect = \ redirect = \
reverse("horizon:admin:providernets:providernets:detail", reverse("horizon:admin:datanets:datanets:detail",
args=(self.kwargs['providernet_id'],)) args=(self.kwargs['providernet_id'],))
msg = _('Unable to retrieve provider network range details') msg = _('Unable to retrieve provider network range details')
exceptions.handle(self.request, msg, redirect=redirect) exceptions.handle(self.request, msg, redirect=redirect)

View File

@ -12,12 +12,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2018 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
import logging import logging
from operator import itemgetter # noqa
from django.core.urlresolvers import reverse # noqa from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _ # noqa from django.utils.translation import ugettext_lazy as _ # noqa
@ -26,120 +25,103 @@ from django.utils.translation import ungettext_lazy
from horizon import exceptions from horizon import exceptions
from horizon import tables from horizon import tables
from neutronclient.common import exceptions as neutron_exceptions from cgtsclient import exc as sysinv_exceptions
from starlingx_dashboard import api as stx_api from starlingx_dashboard import api as stx_api
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class DeleteProviderNetwork(tables.DeleteAction): class DeleteDataNetwork(tables.DeleteAction):
@staticmethod @staticmethod
def action_present(count): def action_present(count):
return ungettext_lazy( return ungettext_lazy(
"Delete Provider Network", "Delete Data Network",
"Delete Provider Networks", "Delete Data Networks",
count count
) )
@staticmethod @staticmethod
def action_past(count): def action_past(count):
return ungettext_lazy( return ungettext_lazy(
"Deleted Provider Network", "Deleted Data Network",
"Deleted Provider Networks", "Deleted Data Networks",
count count
) )
def delete(self, request, obj_id): def delete(self, request, obj_id):
try: try:
stx_api.neutron.provider_network_delete(request, obj_id) stx_api.sysinv.data_network_delete(request, obj_id)
except neutron_exceptions.NeutronClientException as e: except sysinv_exceptions.CgtsclientException as e:
LOG.info(str(e)) LOG.info(str(e))
redirect = reverse('horizon:admin:providernets:index') redirect = reverse('horizon:admin:datanets:index')
exceptions.handle(request, str(e), redirect=redirect) exceptions.handle(request, str(e), redirect=redirect)
except Exception: except Exception:
msg = _('Failed to delete provider network %s') % obj_id msg = _('Failed to delete data network %s') % obj_id
LOG.info(msg) LOG.info(msg)
redirect = reverse('horizon:admin:providernets:index') redirect = reverse('horizon:admin:datanets:index')
exceptions.handle(request, msg, redirect=redirect) exceptions.handle(request, msg, redirect=redirect)
class CreateProviderNetwork(tables.LinkAction): class CreateDataNetwork(tables.LinkAction):
name = "create" name = "create"
verbose_name = _("Create Provider Network") verbose_name = _("Create Data Network")
url = "horizon:admin:providernets:providernets:create" url = "horizon:admin:datanets:datanets:create"
classes = ("ajax-modal", "btn-create") classes = ("ajax-modal", "btn-create")
class EditProviderNetwork(tables.LinkAction): class EditDataNetwork(tables.LinkAction):
name = "update" name = "update"
verbose_name = _("Edit Provider Network") verbose_name = _("Edit Data Network")
url = "horizon:admin:providernets:providernets:update" url = "horizon:admin:datanets:datanets:update"
classes = ("ajax-modal", "btn-edit") classes = ("ajax-modal", "btn-edit")
class AddProviderNetworkRange(tables.LinkAction): class AddDataNetworkRange(tables.LinkAction):
name = "addrange" name = "addrange"
verbose_name = _("Create Segmentation Range") verbose_name = _("Create Segmentation Range")
url = "horizon:admin:providernets:providernets:addrange" url = "horizon:admin:datanets:datanets:addrange"
classes = ("ajax-modal", "btn-edit") classes = ("ajax-modal", "btn-edit")
def allowed(self, request, providernet): def allowed(self, request, providernet):
if providernet: if providernet:
return providernet.type not in ('flat') return providernet.network_type not in ('flat')
return super(AddProviderNetworkRange, self).allowed(request, return super(AddDataNetworkRange, self).allowed(request,
providernet) providernet)
class ProviderNetworksFilterAction(tables.FilterAction): class DataNetworksFilterAction(tables.FilterAction):
def filter(self, table, providernets, filter_string): def filter(self, table, datanets, filter_string):
"""Naive case-insensitive search.""" """Naive case-insensitive search."""
q = filter_string.lower() q = filter_string.lower()
return [providernet for providernet in providernets return [providernet for providernet in datanets
if q in providernet.name.lower()] if q in providernet.name.lower()]
def _format_providernet_ranges(data): def _format_providernet_ranges(data):
ranges = data['ranges'] # TODO(datanetworks): update ranges based upon Stein spec
if not ranges: return '-'
return '-'
return ", ".join(["{}-{}".format(r['minimum'], r['maximum'])
if r['minimum'] != r['maximum']
else "{}".format(r['minimum'])
for r in sorted(ranges, key=itemgetter('minimum'))])
PROVIDERNET_STATUS_CHOICES = ( class DataNetworksTable(tables.DataTable):
('active', True),
('down', False),
('error', False),
('unmanaged', True)
)
class ProviderNetworksTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Network Name"), name = tables.Column("name", verbose_name=_("Network Name"),
link='horizon:admin:providernets:providernets:detail') link='horizon:admin:datanets:datanets:detail')
status = tables.Column("status", type = tables.Column("network_type", verbose_name=_("Type"))
verbose_name=_("Status"),
status=True,
status_choices=PROVIDERNET_STATUS_CHOICES)
type = tables.Column("type", verbose_name=_("Type"))
mtu = tables.Column("mtu", verbose_name=_("MTU")) mtu = tables.Column("mtu", verbose_name=_("MTU"))
ranges = tables.Column(transform=_format_providernet_ranges, ranges = tables.Column(transform=_format_providernet_ranges,
verbose_name=_("Segmentation Ranges")) verbose_name=_("Segmentation Ranges"))
vlan_transparent = tables.Column("vlan_transparent",
verbose_name=_("VLAN Transparent")) def get_object_id(self, datum):
return str(datum.uuid)
class Meta(object): class Meta(object):
name = "provider_networks" name = "provider_networks"
verbose_name = _("Provider Networks") verbose_name = _("Data Networks")
status_columns = ["status"] table_actions = (CreateDataNetwork, DeleteDataNetwork,
table_actions = (CreateProviderNetwork, DeleteProviderNetwork, DataNetworksFilterAction)
ProviderNetworksFilterAction) row_actions = (EditDataNetwork,
row_actions = (EditProviderNetwork, DeleteDataNetwork,
DeleteProviderNetwork, AddDataNetworkRange)
AddProviderNetworkRange)
def _get_link_url(datum): def _get_link_url(datum):

View File

@ -12,22 +12,22 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2015 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
from django.conf.urls import include # noqa from django.conf.urls import include # noqa
from django.conf.urls import url # noqa from django.conf.urls import url # noqa
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import urls as range_urls import urls as range_urls
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import views as range_views import views as range_views
from starlingx_dashboard.dashboards.admin.providernets.providernets import \ from starlingx_dashboard.dashboards.admin.datanets.datanets import \
views views
PROVIDERNETS = r'^(?P<providernet_id>[^/]+)/%s$' PROVIDERNETS = r'^(?P<providernet_id>[^/]+)/%s$'
VIEW_MOD = 'starlingx_dashboard.dashboards.admin.providernets.providernets.' \ VIEW_MOD = 'starlingx_dashboard.dashboards.admin.datanets.datanets.' \
'views' 'views'
urlpatterns = [ urlpatterns = [

View File

@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
# Copyright (c) 2013-2014 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
@ -30,30 +30,30 @@ from horizon import tables
from openstack_dashboard import api from openstack_dashboard import api
from starlingx_dashboard import api as stx_api from starlingx_dashboard import api as stx_api
from starlingx_dashboard.dashboards.admin.providernets.providernets import \ from starlingx_dashboard.dashboards.admin.datanets.datanets import \
forms as providernet_forms forms as datanet_forms
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import tables as range_tables import tables as range_tables
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \ from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import views as range_views import views as range_views
from starlingx_dashboard.dashboards.admin.providernets.providernets import \ from starlingx_dashboard.dashboards.admin.datanets.datanets import \
tables as providernet_tables tables as providernet_tables
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class CreateView(forms.ModalFormView): class CreateView(forms.ModalFormView):
form_class = providernet_forms.CreateProviderNetwork form_class = datanet_forms.CreateDataNetwork
template_name = 'admin/providernets/providernets/create.html' template_name = 'admin/datanets/datanets/create.html'
success_url = reverse_lazy('horizon:admin:providernets:index') success_url = reverse_lazy('horizon:admin:datanets:index')
class DetailView(tables.MultiTableView): class DetailView(tables.MultiTableView):
table_classes = (range_tables.ProviderNetworkRangeTable, table_classes = (range_tables.ProviderNetworkRangeTable,
providernet_tables.ProviderNetworkTenantNetworkTable) providernet_tables.ProviderNetworkTenantNetworkTable)
template_name = 'admin/providernets/providernets/detail.html' template_name = 'admin/datanets/datanets/detail.html'
failure_url = reverse_lazy('horizon:admin:providernets:index') failure_url = reverse_lazy('horizon:admin:datanets:index')
page_title = '{{ "Provider Network Detail: "|add:providernet.name }}' page_title = '{{ "Data Network Detail: "|add:providernet.name }}'
def _get_tenant_list(self): def _get_tenant_list(self):
if not hasattr(self, "_tenants"): if not hasattr(self, "_tenants"):
@ -69,10 +69,8 @@ class DetailView(tables.MultiTableView):
def get_tenant_networks_data(self): def get_tenant_networks_data(self):
try: try:
providernet_id = self.kwargs['providernet_id'] # TODO(datanetworks): get tenant networks when in upstream neutron
# self.table.kwargs['providernet'] = self._get_data() networks = []
networks = stx_api.neutron.provider_network_list_tenant_networks(
self.request, providernet_id=providernet_id)
except Exception: except Exception:
networks = [] networks = []
msg = _('Tenant network list can not be retrieved.') msg = _('Tenant network list can not be retrieved.')
@ -81,10 +79,8 @@ class DetailView(tables.MultiTableView):
def get_provider_network_ranges_data(self): def get_provider_network_ranges_data(self):
try: try:
providernet_id = self.kwargs['providernet_id'] # TODO(datanetworks) force ranges to []
# self.table.kwargs['providernet'] = self._get_data() ranges = []
ranges = stx_api.neutron.provider_network_range_list(
self.request, providernet_id=providernet_id)
except Exception: except Exception:
ranges = [] ranges = []
msg = _('Segmentation id range list can not be retrieved.') msg = _('Segmentation id range list can not be retrieved.')
@ -101,9 +97,8 @@ class DetailView(tables.MultiTableView):
if not hasattr(self, "_providernet"): if not hasattr(self, "_providernet"):
try: try:
providernet_id = self.kwargs['providernet_id'] providernet_id = self.kwargs['providernet_id']
providernet = stx_api.neutron.provider_network_get( providernet = stx_api.sysinv.data_network_get(
self.request, providernet_id) self.request, providernet_id)
providernet.set_id_as_name_if_empty(length=0)
except Exception: except Exception:
redirect = self.failure_url redirect = self.failure_url
exceptions.handle(self.request, exceptions.handle(self.request,
@ -115,20 +110,8 @@ class DetailView(tables.MultiTableView):
def _get_nova_data(self): def _get_nova_data(self):
if not hasattr(self, "_providernet_nova"): if not hasattr(self, "_providernet_nova"):
try: # TODO(datanetworks): depends on upstream support
providernet_id = self.kwargs['providernet_id'] self._providernet_nova = None
providernet_nova = stx_api.nova.provider_network_get(
self.request, providernet_id)
except Exception as ex:
# redirect = self.failure_url
# exceptions.handle(self.request,
# _('Unable to retrieve details for '
# 'provider network "%s".') % providernet_id,
# redirect=redirect)
LOG.error(ex)
providernet_nova = None
self._providernet_nova = providernet_nova
return self._providernet_nova return self._providernet_nova
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -139,9 +122,9 @@ class DetailView(tables.MultiTableView):
class UpdateView(forms.ModalFormView): class UpdateView(forms.ModalFormView):
form_class = providernet_forms.UpdateProviderNetwork form_class = datanet_forms.UpdateDataNetwork
template_name = 'admin/providernets/providernets/update.html' template_name = 'admin/datanets/datanets/update.html'
success_url = reverse_lazy('horizon:admin:providernets:index') success_url = reverse_lazy('horizon:admin:datanets:index')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs) context = super(UpdateView, self).get_context_data(**kwargs)
@ -152,28 +135,28 @@ class UpdateView(forms.ModalFormView):
if not hasattr(self, "_object"): if not hasattr(self, "_object"):
providernet_id = self.kwargs['providernet_id'] providernet_id = self.kwargs['providernet_id']
try: try:
self._object = stx_api.neutron.provider_network_get( self._object = stx_api.sysinv.data_network_get(
self.request, providernet_id) self.request, providernet_id)
except Exception: except Exception:
redirect = self.success_url redirect = self.success_url
msg = _('Unable to retrieve provider network details.') msg = _('Unable to retrieve data network details.')
exceptions.handle(self.request, msg, redirect=redirect) exceptions.handle(self.request, msg, redirect=redirect)
return self._object return self._object
def get_initial(self): def get_initial(self):
providernet = self._get_object() providernet = self._get_object()
return {'id': providernet['id'], return {'id': providernet.id,
'name': providernet['name'], 'name': providernet.name,
'description': providernet['description'], 'network_type': providernet.network_type,
'type': providernet['type'], 'mtu': providernet.mtu,
'mtu': providernet['mtu'], 'description': providernet.description,
'vlan_transparent': providernet['vlan_transparent']} }
class CreateRangeView(range_views.CreateView): class CreateRangeView(range_views.CreateView):
template_name = 'admin/providernets/providernets/add_range.html' template_name = 'admin/datanets/datanets/add_range.html'
success_url = 'horizon:admin:providernets:index' success_url = 'horizon:admin:datanets:index'
failure_url = 'horizon:admin:providernets:index' failure_url = 'horizon:admin:datanets:index'
def get_success_url(self): def get_success_url(self):
return reverse(self.success_url) return reverse(self.success_url)

View File

@ -11,9 +11,9 @@ from openstack_dashboard.api import base
from openstack_dashboard.dashboards.admin import dashboard from openstack_dashboard.dashboards.admin import dashboard
class Providernets(horizon.Panel): class Datanets(horizon.Panel):
name = _("Provider Networks") name = _("Data Networks")
slug = 'providernets' slug = 'datanets'
permissions = ('openstack.services.platform', 'openstack.services.network') permissions = ('openstack.services.platform', 'openstack.services.network')
def allowed(self, context): def allowed(self, context):
@ -22,7 +22,7 @@ class Providernets(horizon.Panel):
if not base.is_service_enabled(context['request'], 'platform'): if not base.is_service_enabled(context['request'], 'platform'):
return False return False
else: else:
return super(Providernets, self).allowed(context) return super(Datanets, self).allowed(context)
def nav(self, context): def nav(self, context):
if context['request'].user.services_region == 'SystemController': if context['request'].user.services_region == 'SystemController':
@ -33,4 +33,4 @@ class Providernets(horizon.Panel):
return True return True
dashboard.Admin.register(Providernets) dashboard.Admin.register(Datanets)

View File

@ -1,47 +1,42 @@
# #
# Copyright (c) 2013-2016 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
import logging
from django.utils.translation import ugettext_lazy as _ # noqa from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions from horizon import exceptions
from horizon import tabs from horizon import tabs
from starlingx_dashboard.api import base as stx_base from starlingx_dashboard.api import base as stx_base
from starlingx_dashboard.api import neutron as stx_neutron from starlingx_dashboard.api import sysinv as stx_sysinv
from starlingx_dashboard.dashboards.admin.providernets.providernets import \ from starlingx_dashboard.dashboards.admin.datanets.datanets import \
tables as providernets_tables tables as datanets_tables
LOG = logging.getLogger(__name__)
class ProviderNetworkTab(tabs.TableTab): class DataNetworkTab(tabs.TableTab):
table_classes = (providernets_tables.ProviderNetworksTable,) table_classes = (datanets_tables.DataNetworksTable,)
name = _("Provider Networks") name = _("Data Networks")
slug = "provider_networks" slug = "provider_networks"
template_name = ("horizon/common/_detail_table.html") template_name = ("horizon/common/_detail_table.html")
def get_provider_networks_data(self): def get_provider_networks_data(self):
try: try:
providernets = \ datanets = \
stx_neutron.provider_network_list(self.tab_group.request) stx_sysinv.data_network_list(self.tab_group.request)
except Exception: except Exception:
providernets = [] datanets = []
msg = _('Unable to get provider network list.') msg = _('Unable to get provider network list.')
exceptions.check_message(["Connection", "refused"], msg) exceptions.check_message(["Connection", "refused"], msg)
raise raise
return providernets return datanets
def allowed(self, request): def allowed(self, request):
return stx_base.is_stx_region(request) return stx_base.is_stx_region(request)
class NetworkTabs(tabs.TabGroup): class NetworkTabs(tabs.TabGroup):
slug = "providernets" slug = "datanets"
tabs = (ProviderNetworkTab,) tabs = (DataNetworkTab,)
sticky = True sticky = True

View File

@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% block form_id %}add_provider_network_range_form{% endblock %} {% block form_id %}add_provider_network_range_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:providernets:providernets:addrange' providernet_id %} {% block form_action %}{% url 'horizon:admin:datanets:datanets:addrange' providernet_id %}
{% endblock %} {% endblock %}
{% block modal-header %}{% trans "Create Segmentation Range" %}{% endblock %} {% block modal-header %}{% trans "Create Segmentation Range" %}{% endblock %}

View File

@ -2,10 +2,10 @@
{% load i18n %} {% load i18n %}
{% block form_id %}create_provider_network_form{% endblock %} {% block form_id %}create_provider_network_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:providernets:providernets:create' %} {% block form_action %}{% url 'horizon:admin:datanets:datanets:create' %}
{% endblock %} {% endblock %}
{% block modal-header %}{% trans "Create Provider Network" %}{% endblock %} {% block modal-header %}{% trans "Create Data Network" %}{% endblock %}
{% block modal-body %} {% block modal-body %}
<div class="left"> <div class="left">
@ -21,5 +21,5 @@
{% block modal-footer %} {% block modal-footer %}
<a class="btn btn-default cancel" data-dismiss="modal">{% trans "Cancel" %}</a> <a class="btn btn-default cancel" data-dismiss="modal">{% trans "Cancel" %}</a>
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Provider Network" %}" /> <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Data Network" %}" />
{% endblock %} {% endblock %}

View File

@ -1,6 +1,6 @@
{% load i18n sizeformat %} {% load i18n sizeformat %}
<h3>{% trans "Provider Network Overview" %}</h3> <h3>{% trans "Data Network Overview" %}</h3>
<div class="info detail"> <div class="info detail">
<dl class="dl-horizontal"> <dl class="dl-horizontal">
@ -14,8 +14,6 @@
<dd>{{ providernet.mtu|default:_("-") }}</dd> <dd>{{ providernet.mtu|default:_("-") }}</dd>
<dt>{% trans "Description" %}</dt> <dt>{% trans "Description" %}</dt>
<dd>{{ providernet.description|default:_("None") }}</dd> <dd>{{ providernet.description|default:_("None") }}</dd>
<dt>{% trans "VLAN Transparent" %}</dt>
<dd>{{ providernet.vlan_transparent|yesno|capfirst }}</dd>
{% if nova_providernet %} {% if nova_providernet %}
<dt>{% trans "PCI PFs Configured" %}</dt> <dt>{% trans "PCI PFs Configured" %}</dt>
<dd>{{ nova_providernet.pci_pfs_configured|default:_("0") }}</dd> <dd>{{ nova_providernet.pci_pfs_configured|default:_("0") }}</dd>

View File

@ -2,9 +2,9 @@
{% load i18n %} {% load i18n %}
{% block form_id %}update_provider_network_form{% endblock %} {% block form_id %}update_provider_network_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:providernets:providernets:update' providernet_id %}{% endblock %} {% block form_action %}{% url 'horizon:admin:datanets:datanets:update' providernet_id %}{% endblock %}
{% block modal-header %}{% trans "Edit Provider Network" %}{% endblock %} {% block modal-header %}{% trans "Edit Data Network" %}{% endblock %}
{% block modal-body %} {% block modal-body %}
<div class="left"> <div class="left">
@ -19,7 +19,7 @@
</div> </div>
<div class="right"> <div class="right">
<h3>{% trans "Description:" %}</h3> <h3>{% trans "Description:" %}</h3>
<p>{% trans "You may update the editable properties of your provider network here." %}</p> <p>{% trans "You may update the editable properties of your data network here." %}</p>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -7,5 +7,5 @@
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}
{% include "admin/providernets/providernets/_add_range.html" %} {% include "admin/datanets/datanets/_add_range.html" %}
{% endblock %} {% endblock %}

View File

@ -1,11 +1,11 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Create Provider Network" %}{% endblock %} {% block title %}{% trans "Create Data Network" %}{% endblock %}
{% block page_header %} {% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Create Provider Network") %} {% include "horizon/common/_page_header.html" with title=_("Create Data Network") %}
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}
{% include "admin/providernets/providernets/_create.html" %} {% include "admin/datanets/datanets/_create.html" %}
{% endblock %} {% endblock %}

View File

@ -1,9 +1,9 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n breadcrumb_nav %} {% load i18n breadcrumb_nav %}
{% block title %}{% trans "Provider Network Detail"%}{% endblock %} {% block title %}{% trans "Data Network Detail"%}{% endblock %}
{% block main %} {% block main %}
{% include "admin/providernets/providernets/_detail_overview.html" %} {% include "admin/datanets/datanets/_detail_overview.html" %}
<hr> <hr>
<div id="ranges"> <div id="ranges">
{{ provider_network_ranges_table.render }} {{ provider_network_ranges_table.render }}

View File

@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% block form_id %}create_provider_network_range_form{% endblock %} {% block form_id %}create_provider_network_range_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:providernets:providernets:createrange' providernet_id %} {% block form_action %}{% url 'horizon:admin:datanets:datanets:createrange' providernet_id %}
{% endblock %} {% endblock %}
{% block modal-header %}{% trans "Create Segmentation Range" %}{% endblock %} {% block modal-header %}{% trans "Create Segmentation Range" %}{% endblock %}

View File

@ -18,7 +18,7 @@
<dd>{{ providernet_range.maximum|default:_("None") }}</dd> <dd>{{ providernet_range.maximum|default:_("None") }}</dd>
{% if providernet_range.vxlan %} {% if providernet_range.vxlan %}
<dt>{% trans "Provider Attributes" %}</dt> <dt>{% trans "Provider Attributes" %}</dt>
<dd>{% include "admin/providernets/providernets/ranges/_vxlan.html" with vxlan=providernet_range.vxlan %}</dd> <dd>{% include "admin/datanets/datanets/ranges/_vxlan.html" with vxlan=providernet_range.vxlan %}</dd>
{% endif %} {% endif %}
</dl> </dl>
</div> </div>

View File

@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% block form_id %}update_provider_network_range_form{% endblock %} {% block form_id %}update_provider_network_range_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:providernets:providernets:editrange' providernet_id providernet_range_id %}{% endblock %} {% block form_action %}{% url 'horizon:admin:datanets:datanets:editrange' providernet_id providernet_range_id %}{% endblock %}
{% block modal-header %}{% trans "Edit Segmentation Range" %}{% endblock %} {% block modal-header %}{% trans "Edit Segmentation Range" %}{% endblock %}

View File

@ -7,5 +7,5 @@
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}
{% include "admin/providernets/providernets/ranges/_create.html" %} {% include "admin/datanets/datanets/ranges/_create.html" %}
{% endblock %} {% endblock %}

View File

@ -1,11 +1,11 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Update Provider Network Range" %}{% endblock %} {% block title %}{% trans "Update Data Network Range" %}{% endblock %}
{% block page_header %} {% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Update Provider Network Range") %} {% include "horizon/common/_page_header.html" with title=_("Update Data Network Range") %}
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}
{% include 'admin/providernets/providernets/ranges/_update.html' %} {% include 'admin/datanets/datanets/ranges/_update.html' %}
{% endblock %} {% endblock %}

View File

@ -1,11 +1,11 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Update Provider Network" %}{% endblock %} {% block title %}{% trans "Update Data Network" %}{% endblock %}
{% block page_header %} {% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Update Provider Network") %} {% include "horizon/common/_page_header.html" with title=_("Update Data Network") %}
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}
{% include 'admin/providernets/providernets/_update.html' %} {% include 'admin/datanets/datanets/_update.html' %}
{% endblock %} {% endblock %}

View File

@ -1,9 +1,9 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Provider Networks" %}{% endblock %} {% block title %}{% trans "Data Networks" %}{% endblock %}
{% block page_header %} {% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Provider Networks")%} {% include "horizon/common/_page_header.html" with title=_("Data Networks")%}
{% endblock page_header %} {% endblock page_header %}
{% block main %} {% block main %}

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2013-2016 Wind River Systems, Inc. # Copyright (c) 2013-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -7,15 +7,15 @@
from django.conf.urls import include from django.conf.urls import include
from django.conf.urls import url from django.conf.urls import url
from starlingx_dashboard.dashboards.admin.providernets.providernets \ from starlingx_dashboard.dashboards.admin.datanets.datanets \
import urls as providernet_urls import urls as providernet_urls
from starlingx_dashboard.dashboards.admin.providernets import views from starlingx_dashboard.dashboards.admin.datanets import views
NETWORKS = r'^(?P<network_id>[^/]+)/%s$' NETWORKS = r'^(?P<network_id>[^/]+)/%s$'
urlpatterns = [ urlpatterns = [
url(r'^$', views.IndexViewTabbed.as_view(), name='index'), url(r'^$', views.IndexViewTabbed.as_view(), name='index'),
url(r'^providernets/', url(r'^datanets/',
include(providernet_urls, namespace='providernets')) include(providernet_urls, namespace='datanets'))
] ]

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2016 Wind River Systems, Inc. # Copyright (c) 2016-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -8,11 +8,11 @@ from django.utils.translation import ugettext_lazy as _
from horizon import tabs from horizon import tabs
from starlingx_dashboard.dashboards.admin.providernets \ from starlingx_dashboard.dashboards.admin.datanets \
import tabs as project_tabs import tabs as project_tabs
class IndexViewTabbed(tabs.TabbedTableView): class IndexViewTabbed(tabs.TabbedTableView):
tab_group_class = project_tabs.NetworkTabs tab_group_class = project_tabs.NetworkTabs
template_name = 'admin/providernets/tabs.html' template_name = 'admin/datanets/tabs.html'
page_title = _("Provider Networks") page_title = _("Data Networks")

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2016-2018 Wind River Systems, Inc. # Copyright (c) 2016-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -14,7 +14,7 @@ from openstack_dashboard.dashboards.admin import dashboard
class HostTopology(horizon.Panel): class HostTopology(horizon.Panel):
name = _("Provider Network Topology") name = _("Data Network Topology")
slug = 'host_topology' slug = 'host_topology'
permissions = ('openstack.services.platform', 'openstack.services.network') permissions = ('openstack.services.platform', 'openstack.services.network')

View File

@ -11,10 +11,10 @@ import logging
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from starlingx_dashboard.dashboards.admin.datanets.datanets.ranges \
import tables as sr_tables
from starlingx_dashboard.dashboards.admin.inventory.interfaces import \ from starlingx_dashboard.dashboards.admin.inventory.interfaces import \
tables as if_tables tables as if_tables
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \
import tables as sr_tables
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)

View File

@ -1,4 +1,4 @@
# Copyright (c) 2016-2018 Wind River Systems, Inc. # Copyright (c) 2016-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -15,12 +15,12 @@ from horizon import tabs
from openstack_dashboard import api as api from openstack_dashboard import api as api
from starlingx_dashboard import api as stx_api from starlingx_dashboard import api as stx_api
from starlingx_dashboard.dashboards.admin.datanets.datanets import \
tables as pn_tables
from starlingx_dashboard.dashboards.admin.host_topology import \ from starlingx_dashboard.dashboards.admin.host_topology import \
tables as tables tables as tables
from starlingx_dashboard.dashboards.admin.inventory import \ from starlingx_dashboard.dashboards.admin.inventory import \
tabs as i_tabs tabs as i_tabs
from starlingx_dashboard.dashboards.admin.providernets.providernets import \
tables as pn_tables
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -66,7 +66,7 @@ class OverviewTab(tabs.TableTab):
table_classes = (tables.ProviderNetworkRangeTable, table_classes = (tables.ProviderNetworkRangeTable,
pn_tables.ProviderNetworkTenantNetworkTable) pn_tables.ProviderNetworkTenantNetworkTable)
template_name = 'admin/host_topology/detail/providernet.html' template_name = 'admin/host_topology/detail/providernet.html'
name = "Provider Network Detail" name = "Data Network Detail"
slug = 'providernet_details_overview' slug = 'providernet_details_overview'
failure_url = reverse_lazy('horizon:admin:host_topology:index') failure_url = reverse_lazy('horizon:admin:host_topology:index')
@ -83,14 +83,8 @@ class OverviewTab(tabs.TableTab):
return self._tenants return self._tenants
def get_tenant_networks_data(self): def get_tenant_networks_data(self):
try: # TODO(datanetworks): need to refactor for Stein
providernet_id = self.tab_group.kwargs['providernet_id'] networks = []
networks = stx_api.neutron.provider_network_list_tenant_networks(
self.request, providernet_id=providernet_id)
except Exception:
networks = []
msg = _('Tenant network list can not be retrieved.')
exceptions.handle(self.request, msg)
return networks return networks
def get_provider_network_ranges_data(self): def get_provider_network_ranges_data(self):

View File

@ -156,8 +156,8 @@ svg#topology_canvas g.loading .host .icon_bg {
<input id="host_list_search" class="form-control" type="text" placeholder="Search Worker Hosts" /> <input id="host_list_search" class="form-control" type="text" placeholder="Search Worker Hosts" />
<div id="host_list" class="list-group"> <div id="host_list" class="list-group">
</div> </div>
<h4>Provider Networks</h4> <h4>Data Networks</h4>
<input id="network_list_search" class="form-control" type="text" placeholder="Search Provider Networks" /> <input id="network_list_search" class="form-control" type="text" placeholder="Search Data Networks" />
<div id="network_list" class="list-group"> <div id="network_list" class="list-group">
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
{% load i18n sizeformat %} {% load i18n sizeformat %}
<div class="info row-fluid detail"> <div class="info row-fluid detail">
{% include "admin/providernets/providernets/_detail_overview.html" %} {% include "admin/datanets/datanets/_detail_overview.html" %}
<hr> <hr>
<div id="ranges"> <div id="ranges">
{{ provider_network_ranges_table.render }} {{ provider_network_ranges_table.render }}

View File

@ -4,7 +4,7 @@
{% if host %} {% if host %}
<h4>Selected Entity: <a href="{% url 'horizon:admin:inventory:detail' host.id %}" >{{host.hostname}}</a></h4> <h4>Selected Entity: <a href="{% url 'horizon:admin:inventory:detail' host.id %}" >{{host.hostname}}</a></h4>
{% else %} {% else %}
<h4>Selected Entity: <a href="{% url 'horizon:admin:providernets:providernets:detail' providernet.id %}" >{{providernet.name}}</a></h4> <h4>Selected Entity: <a href="{% url 'horizon:admin:datanets:datanets:detail' providernet.id %}" >{{providernet.name}}</a></h4>
{% endif %} {% endif %}
{% block main %} {% block main %}

View File

@ -1,6 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Provider Network Topology" %}{% endblock %} {% block title %}{% trans "Data Network Topology" %}{% endblock %}
{% block main %} {% block main %}

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2016-2018 Wind River Systems, Inc. # Copyright (c) 2016-2019 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -73,9 +73,8 @@ class ProvidernetDetailView(tabs.TabbedTableView):
if not hasattr(self, "_providernet"): if not hasattr(self, "_providernet"):
try: try:
providernet_id = self.kwargs['providernet_id'] providernet_id = self.kwargs['providernet_id']
providernet = stx_api.neutron.provider_network_get( providernet = stx_api.sysinv.data_network_get(
self.request, providernet_id) self.request, providernet_id)
providernet.set_id_as_name_if_empty(length=0)
alarms = stx_api.fm.alarm_list(self.request) alarms = stx_api.fm.alarm_list(self.request)
# Filter out unrelated alarms # Filter out unrelated alarms
@ -98,18 +97,8 @@ class ProvidernetDetailView(tabs.TabbedTableView):
def get_nova_data(self): def get_nova_data(self):
if not hasattr(self, "_providernet_nova"): if not hasattr(self, "_providernet_nova"):
try: # TODO(datanetworks): depends on upstream support
providernet_id = self.kwargs['providernet_id'] self._providernet_nova = None
providernet_nova = stx_api.nova.provider_network_get(
self.request, providernet_id)
except Exception:
redirect = self.failure_url
exceptions.handle(self.request,
_('Unable to retrieve details for '
'provider network "%s".') % providernet_id,
redirect=redirect)
self._providernet_nova = providernet_nova
return self._providernet_nova return self._providernet_nova
def get_tabs(self, request, *args, **kwargs): def get_tabs(self, request, *args, **kwargs):
@ -122,7 +111,7 @@ class ProvidernetDetailView(tabs.TabbedTableView):
class HostTopologyView(views.HorizonTemplateView): class HostTopologyView(views.HorizonTemplateView):
template_name = 'admin/host_topology/index.html' template_name = 'admin/host_topology/index.html'
page_title = _("Provider Network Topology") page_title = _("Data Network Topology")
def _has_permission(self, policy): def _has_permission(self, policy):
has_permission = True has_permission = True
@ -220,7 +209,7 @@ class JSONView(View):
def _get_pnets(self, request): def _get_pnets(self, request):
pnets = [] pnets = []
try: try:
pnets = stx_api.neutron.provider_network_list(request) pnets = stx_api.sysinv.data_network_list(request)
except Exception as ex: except Exception as ex:
exceptions.handle(ex) exceptions.handle(ex)
data = [p.to_dict() for p in pnets] data = [p.to_dict() for p in pnets]

View File

@ -23,7 +23,6 @@ from horizon import exceptions
from horizon import forms from horizon import forms
from horizon import messages from horizon import messages
from starlingx_dashboard.api import neutron
from starlingx_dashboard.api import sysinv from starlingx_dashboard.api import sysinv
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -280,37 +279,37 @@ class AddInterface(forms.SelfHandlingForm):
'data-switch-on': 'ifclass', 'data-switch-on': 'ifclass',
'data-ifclass-platform': 'Platform Network(s)'})) 'data-ifclass-platform': 'Platform Network(s)'}))
providernetworks_data = MultipleChoiceField( datanetworks_data = MultipleChoiceField(
label=_("Provider Network(s)"), label=_("Data Network(s)"),
required=False, required=False,
widget=CheckboxSelectMultiple( widget=CheckboxSelectMultiple(
attrs={ attrs={
'class': 'switched', 'class': 'switched',
'data-switch-on': 'ifclass', 'data-switch-on': 'ifclass',
'data-ifclass-data': ''}, 'data-ifclass-data': ''},
empty_value=_("No provider networks available " empty_value=_("No data networks available "
"for this interface class."))) "for this interface class.")))
providernetworks_pci = MultipleChoiceField( datanetworks_pci = MultipleChoiceField(
label=_("Provider Network(s)"), label=_("Data Network(s)"),
required=False, required=False,
widget=CheckboxSelectMultiple( widget=CheckboxSelectMultiple(
attrs={ attrs={
'class': 'switched', 'class': 'switched',
'data-switch-on': 'ifclass', 'data-switch-on': 'ifclass',
'data-ifclass-pci-passthrough': ''}, 'data-ifclass-pci-passthrough': ''},
empty_value=_("No provider networks available " empty_value=_("No data networks available "
"for this interface class."))) "for this interface class.")))
providernetworks_sriov = MultipleChoiceField( datanetworks_sriov = MultipleChoiceField(
label=_("Provider Network(s)"), label=_("Data Network(s)"),
required=False, required=False,
widget=CheckboxSelectMultiple( widget=CheckboxSelectMultiple(
attrs={ attrs={
'class': 'switched', 'class': 'switched',
'data-switch-on': 'ifclass', 'data-switch-on': 'ifclass',
'data-ifclass-pci-sriov': ''}, 'data-ifclass-pci-sriov': ''},
empty_value=_("No provider networks available " empty_value=_("No data networks available "
"for this interface class."))) "for this interface class.")))
imtu = forms.IntegerField( imtu = forms.IntegerField(
@ -383,9 +382,9 @@ class AddInterface(forms.SelfHandlingForm):
current_interface = sysinv.host_interface_get( current_interface = sysinv.host_interface_get(
self.request, this_interface_id) self.request, this_interface_id)
else: else:
self.fields['providernetworks_sriov'].widget = \ self.fields['datanetworks_sriov'].widget = \
forms.widgets.HiddenInput() forms.widgets.HiddenInput()
self.fields['providernetworks_pci'].widget = \ self.fields['datanetworks_pci'].widget = \
forms.widgets.HiddenInput() forms.widgets.HiddenInput()
host_uuid = kwargs['initial']['ihost_uuid'] host_uuid = kwargs['initial']['ihost_uuid']
@ -400,38 +399,38 @@ class AddInterface(forms.SelfHandlingForm):
network_choices = _get_network_choices(networks) network_choices = _get_network_choices(networks)
self.fields['networks'].choices = network_choices self.fields['networks'].choices = network_choices
# Populate Provider Network Choices by querying Neutron # Populate Data Network Choices by querying SysInv
self.extras = {} self.extras = {}
interfaces = sysinv.host_interface_list(self.request, host_uuid) interfaces = sysinv.host_interface_list(self.request, host_uuid)
used_providernets = [] used_datanets = []
for i in interfaces: for i in interfaces:
if i.ifclass == 'data' and \ if i.ifclass == 'data' and \
i.providernetworks and \ i.datanetworks_csv and \
i.uuid != this_interface_id: i.uuid != this_interface_id:
used_providernets = used_providernets + \ used_datanets = used_datanets + \
i.providernetworks.split(",") i.datanetworks_csv.split(",")
providernet_choices = [] datanet_choices = []
providernet_filtered = [] datanet_filtered = []
if getattr(self.request.user, 'services_region', None) == 'RegionOne' \ if getattr(self.request.user, 'services_region', None) == 'RegionOne' \
and getattr(settings, 'DC_MODE', False): and getattr(settings, 'DC_MODE', False):
nt_choices = self.fields['ifclass'].choices nt_choices = self.fields['ifclass'].choices
self.fields['ifclass'].choices = [i for i in nt_choices if self.fields['ifclass'].choices = [i for i in nt_choices if
i[0] != 'data'] i[0] != 'data']
else: else:
providernets = neutron.provider_network_list(self.request) datanets = sysinv.data_network_list(self.request)
for provider in providernets: for dn in datanets:
label = "{} (mtu={})".format(provider.name, provider.mtu) label = "{} (mtu={})".format(dn.name, dn.mtu)
providernet = (str(provider.name), label) datanet = (str(dn.name), label)
providernet_choices.append(providernet) datanet_choices.append(datanet)
if provider.name not in used_providernets: if dn.name not in used_datanets:
providernet_filtered.append(providernet) datanet_filtered.append(datanet)
self.fields['providernetworks_data'].choices = providernet_filtered self.fields['datanetworks_data'].choices = datanet_filtered
if (type(self) is UpdateInterface): if (type(self) is UpdateInterface):
self.fields['providernetworks_pci'].choices = providernet_choices self.fields['datanetworks_pci'].choices = datanet_choices
self.fields['providernetworks_sriov'].choices = providernet_choices self.fields['datanetworks_sriov'].choices = datanet_choices
if current_interface: if current_interface:
# update operation # update operation
@ -493,35 +492,35 @@ class AddInterface(forms.SelfHandlingForm):
cleaned_data.pop('ipv6_pool', None) cleaned_data.pop('ipv6_pool', None)
if ifclass == 'data': if ifclass == 'data':
providernetworks = [_f for _f in cleaned_data.get( datanetworks = [_f for _f in cleaned_data.get(
'providernetworks_data', []) if _f] 'datanetworks_data', []) if _f]
elif ifclass == 'pci-passthrough': elif ifclass == 'pci-passthrough':
providernetworks = [_f for _f in cleaned_data.get( datanetworks = [_f for _f in cleaned_data.get(
'providernetworks_pci', []) if _f] 'datanetworks_pci', []) if _f]
elif ifclass == 'pci-sriov': elif ifclass == 'pci-sriov':
providernetworks = [_f for _f in cleaned_data.get( datanetworks = [_f for _f in cleaned_data.get(
'providernetworks_sriov', []) if _f] 'datanetworks_sriov', []) if _f]
else: else:
providernetworks = [] datanetworks = []
# providernetwork selection is required for 'data', 'pci-passthrough' # datanetwork selection is required for 'data', 'pci-passthrough'
# and 'pci-sriov'. It is NOT required for any other interface class # and 'pci-sriov'. It is NOT required for any other interface class
if not providernetworks: if not datanetworks:
# Note that 1 of 3 different controls may be used to select # Note that 1 of 3 different controls may be used to select
# provider network, make sure to set the error on the appropriate # data network, make sure to set the error on the appropriate
# control # control
if ifclass in ['data', 'pci-passthrough', 'pci-sriov']: if ifclass in ['data', 'pci-passthrough', 'pci-sriov']:
raise forms.ValidationError(_( raise forms.ValidationError(_(
"You must specify a Provider Network")) "You must specify a Data Network"))
cleaned_data['providernetworks'] = ",".join(providernetworks) cleaned_data['datanetworks'] = ",".join(datanetworks)
if 'providernetworks_data' in cleaned_data: if 'datanetworks_data' in cleaned_data:
del cleaned_data['providernetworks_data'] del cleaned_data['datanetworks_data']
if 'providernetworks_pci' in cleaned_data: if 'datanetworks_pci' in cleaned_data:
del cleaned_data['providernetworks_pci'] del cleaned_data['datanetworks_pci']
if 'providernetworks_sriov' in cleaned_data: if 'datanetworks_sriov' in cleaned_data:
del cleaned_data['providernetworks_sriov'] del cleaned_data['datanetworks_sriov']
return cleaned_data return cleaned_data
@ -538,8 +537,8 @@ class AddInterface(forms.SelfHandlingForm):
data['uses'] = uses data['uses'] = uses
del data['ports'] del data['ports']
if not data['providernetworks']: if not data['datanetworks']:
del data['providernetworks'] del data['datanetworks']
if not data['vlan_id'] or data['iftype'] != 'vlan': if not data['vlan_id'] or data['iftype'] != 'vlan':
del data['vlan_id'] del data['vlan_id']
@ -813,10 +812,10 @@ class UpdateInterface(AddInterface):
break break
if current_interface.ifclass == 'data': if current_interface.ifclass == 'data':
data['providernetworks'] = 'none' data['datanetworks'] = 'none'
if not data['providernetworks']: if not data['datanetworks']:
del data['providernetworks'] del data['datanetworks']
if 'sriov_numvfs' in data: if 'sriov_numvfs' in data:
data['sriov_numvfs'] = str(data['sriov_numvfs']) data['sriov_numvfs'] = str(data['sriov_numvfs'])

View File

@ -194,8 +194,8 @@ class InterfacesTable(tables.DataTable):
platform_networks = tables.Column(get_platform_networks, platform_networks = tables.Column(get_platform_networks,
verbose_name=_('Platform Network(s)')) verbose_name=_('Platform Network(s)'))
providernetworks = tables.Column('providernetworks', datanetworks_csv = tables.Column('datanetworks_csv',
verbose_name=_('Provider Network(s)')) verbose_name=_('Data Network(s)'))
attributes = tables.Column(get_attributes, attributes = tables.Column(get_attributes,
verbose_name=_('Attributes')) verbose_name=_('Attributes'))

View File

@ -260,10 +260,10 @@ class UpdateView(forms.ModalFormView):
def get_initial(self): def get_initial(self):
interface = self._get_object() interface = self._get_object()
providernetworks = [] datanetworks_csv = []
if interface.providernetworks: if interface.datanetworks_csv:
for pn in interface.providernetworks.split(","): for pn in interface.datanetworks_csv.split(","):
providernetworks.append(str(pn)) datanetworks_csv.append(str(pn))
try: try:
host = stx_api.sysinv.host_get(self.request, interface.host_id) host = stx_api.sysinv.host_get(self.request, interface.host_id)
except Exception: except Exception:
@ -290,10 +290,10 @@ class UpdateView(forms.ModalFormView):
# 'uses': interface.uses, # 'uses': interface.uses,
'ifclass': interface.ifclass, 'ifclass': interface.ifclass,
'networktype': interface.networktype, 'networktype': interface.networktype,
'providernetworks_data': providernetworks, 'datanetworks_csv_data': datanetworks_csv,
'providernetworks_data-external': providernetworks, 'datanetworks_csv_data-external': datanetworks_csv,
'providernetworks_pci': providernetworks, 'datanetworks_csv_pci': datanetworks_csv,
'providernetworks_sriov': providernetworks, 'datanetworks_csv_sriov': datanetworks_csv,
'sriov_numvfs': interface.sriov_numvfs, 'sriov_numvfs': interface.sriov_numvfs,
'imtu': interface.imtu, 'imtu': interface.imtu,
'ipv4_mode': getattr(interface, 'ipv4_mode', 'disabled'), 'ipv4_mode': getattr(interface, 'ipv4_mode', 'disabled'),

View File

@ -2,7 +2,7 @@
<li> <li>
<strong>{{ interfaces.ifname }}</strong> {{": "}} {{ interfaces.ifclass }} <strong>{{ interfaces.ifname }}</strong> {{": "}} {{ interfaces.ifclass }}
{% if interfaces.ifclass == 'data' %} {% if interfaces.ifclass == 'data' %}
{{"("}} {{ interfaces.providernetworks }} {{")"}} {{"("}} {{ interfaces.datanetworks_csv }} {{")"}}
{% endif %} {% endif %}
{{ " | " }} {{ interfaces.iftype }} {{ " | " }} {{ interfaces.iftype }}
{% if interfaces.iftype != 'ae' and interfaces.iftype != 'vlan' %} {% if interfaces.iftype != 'ae' and interfaces.iftype != 'vlan' %}

View File

@ -29,7 +29,7 @@
<li> <li>
<strong>{{ interfaces.ifname }}</strong> {{": "}} {{ interfaces.ifclass }} <strong>{{ interfaces.ifname }}</strong> {{": "}} {{ interfaces.ifclass }}
{% if interfaces.ifclass == 'data' %} {% if interfaces.ifclass == 'data' %}
{{"("}} {{ interfaces.providernetworks }} {{")"}} {{"("}} {{ interfaces.datanetworks_csv }} {{")"}}
{% endif %} {% endif %}
{{ " | " }} {{ interfaces.iftype }} {{ " | " }} {{ interfaces.iftype }}
{% if interfaces.iftype != 'ae' and interfaces.iftype != 'vlan' %} {% if interfaces.iftype != 'ae' and interfaces.iftype != 'vlan' %}

View File

@ -19,8 +19,8 @@
<dt>{% trans "Interface Class" %}</dt> <dt>{% trans "Interface Class" %}</dt>
<dd>{{ interface.ifclass|default:_("None") }}</dd> <dd>{{ interface.ifclass|default:_("None") }}</dd>
{% if interface.ifclass == "data" %} {% if interface.ifclass == "data" %}
<dt>{% trans "Provider Networks" %}</dt> <dt>{% trans "Data Networks" %}</dt>
<dd>{{ interface.providernetworks|default:_("None") }}</dd> <dd>{{ interface.datanetworks_csv|default:_("None") }}</dd>
<dt>{% trans "IPv4 Mode" %}</dt> <dt>{% trans "IPv4 Mode" %}</dt>
<dd>{{ interface.ipv4_mode|default:_("Disabled") }}</dd> <dd>{{ interface.ipv4_mode|default:_("Disabled") }}</dd>
{% if interface.ipv4_mode == "pool" %} {% if interface.ipv4_mode == "pool" %}

View File

@ -1,157 +0,0 @@
# Copyright 2012 NEC Corporation
#
# 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.
#
# Copyright (c) 2013-2018 Wind River Systems, Inc.
#
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _ # noqa
from neutronclient.common import exceptions as neutron_exceptions
from horizon import exceptions
from horizon import forms
from horizon import messages
from starlingx_dashboard import api as stx_api
LOG = logging.getLogger(__name__)
class CreateProviderNetwork(forms.SelfHandlingForm):
name = forms.CharField(max_length=255,
label=_("Name"),
required=True)
description = forms.CharField(max_length=255,
label=_("Description"),
required=False)
type = forms.ChoiceField(label=_("Type"),
required=True)
mtu = forms.IntegerField(label=_("MTU"),
required=True,
initial=1500,
min_value=576,
max_value=9216,
help_text=(
_("Specifies the maximum MTU value of any associated tenant "
"network. Worker node data interface MTU values must be large "
"enough to support the tenant MTU plus any additional provider "
"encapsulation headers. For example, VXLAN provider MTU of "
"1500 requires a minimum data interface MTU of 1574 bytes (1600 "
"bytes is recommended.")))
vlan_transparent = forms.BooleanField(
label=_("VLAN Transparent"),
initial=False, required=False,
help_text=_("Allow tenant networks to be created that require "
"VLAN tagged packets to be transparently passed through "
"the provider network."))
@classmethod
def _instantiate(cls, request, *args, **kwargs):
return cls(request, *args, **kwargs)
def __init__(self, request, *args, **kwargs):
super(CreateProviderNetwork, self).__init__(request, *args, **kwargs)
providernet_type_choices = [('', _("Select a network type"))]
providernet_types = stx_api.neutron.provider_network_type_list(request)
for providernet_type in providernet_types:
providernet_type_choices.append((providernet_type.type,
providernet_type.type))
self.fields['type'].choices = providernet_type_choices
def clean(self):
cleaned_data = super(CreateProviderNetwork, self).clean()
if len(cleaned_data['name'].lstrip()) == 0:
raise forms.ValidationError('invalid provider name')
return cleaned_data
def handle(self, request, data):
try:
params = {'name': data['name'],
'type': data['type'],
'description': data['description'],
'mtu': data['mtu'],
'vlan_transparent': data['vlan_transparent']}
network = stx_api.neutron.provider_network_create(request,
**params)
msg = (_('Provider network %s was successfully created.') %
data['name'])
LOG.debug(msg)
messages.success(request, msg)
return network
except neutron_exceptions.NeutronClientException as e:
redirect = reverse('horizon:admin:providernets:index')
exceptions.handle(request, str(e), redirect=redirect)
except Exception:
redirect = reverse('horizon:admin:providernets:index')
msg = _('Failed to create provider network %s') % data['name']
exceptions.handle(request, msg, redirect=redirect)
class UpdateProviderNetwork(forms.SelfHandlingForm):
name = forms.CharField(label=_("Name"), required=False,
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
type = forms.CharField(label=_("Type"), required=False,
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
id = forms.CharField(widget=forms.HiddenInput)
# Mutable fields
description = forms.CharField(label=_("Description"), required=False)
mtu = forms.IntegerField(label=_("MTU"),
required=True,
initial=1500,
min_value=576,
max_value=9216,
help_text=(_("Specifies the minimum interface"
" MTU required to support this"
" provider network")))
vlan_transparent = forms.BooleanField(
label=_("VLAN Transparent"),
initial=False, required=False,
help_text=_("Allow tenant networks to be created that require "
"VLAN tagged packets to be transparently passed through "
"the provider network. "
"Changes will not impact existing networks."))
failure_url = 'horizon:admin:providernets:index'
def handle(self, request, data):
try:
params = {'description': data['description'],
'mtu': data['mtu'],
'vlan_transparent': data['vlan_transparent']}
providernet = stx_api.neutron.provider_network_modify(
request, data['id'], **params)
msg = (_('Provider network %s was successfully updated.') %
data['name'])
LOG.debug(msg)
messages.success(request, msg)
return providernet
except neutron_exceptions.NeutronClientException as e:
msg = _('Failed to update provider network %s') % data['name']
LOG.info(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, str(e), redirect=redirect)
except Exception:
msg = _('Failed to update provider network %s') % data['name']
LOG.info(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)

View File

@ -1,5 +1,5 @@
# The slug of the panel to be added to HORIZON_CONFIG. Required. # The slug of the panel to be added to HORIZON_CONFIG. Required.
PANEL = 'providernets' PANEL = 'datanets'
# The slug of the dashboard the PANEL associated with. Required. # The slug of the dashboard the PANEL associated with. Required.
PANEL_DASHBOARD = 'admin' PANEL_DASHBOARD = 'admin'
# The slug of the panel group the PANEL is associated with. # The slug of the panel group the PANEL is associated with.
@ -7,4 +7,4 @@ PANEL_GROUP = 'platform'
# Python panel class of the PANEL to be added. # Python panel class of the PANEL to be added.
ADD_PANEL = ('starlingx_dashboard.dashboards.admin.' ADD_PANEL = ('starlingx_dashboard.dashboards.admin.'
'providernets.panel.Providernets') 'datanets.panel.Datanets')

View File

@ -186,8 +186,8 @@ horizon.host_topology = {
// 'expand' a single IF connected to many pnets into multiple 'connections' // 'expand' a single IF connected to many pnets into multiple 'connections'
$.each(host.interfaces, function(index, interface) { $.each(host.interfaces, function(index, interface) {
var if_connections = [] var if_connections = []
if (interface.providernetworks) { if (interface.datanetworks_csv) {
$.each(interface.providernetworks.split(','), function(index, providernet_name) { $.each(interface.datanetworks_csv.split(','), function(index, providernet_name) {
var connection = {} var connection = {}
// Attach the interface to the connection // Attach the interface to the connection
connection.interface = interface; connection.interface = interface;