Create share network panel workflows
Implements: bp share-network-subnets Co-Authored-By: Cameron Kolodjski <cdkolod@gmail.com> Co-Authored-By: Shkoh Hamasoor <shkoh.hamasoor@ndsu.edu> Co-Authored-By: melakualehegn <melakualehegn34@gmail.com> Change-Id: I4c539b151cbbf69e4a2a3580906b2a8bd5f3a452 Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
parent
99138f186a
commit
d1428c5fc5
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,6 +22,7 @@ lib64
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
coverage.xml
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
|
@ -28,7 +28,7 @@ from manilaclient import client as manila_client
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
MANILA_UI_USER_AGENT_REPR = "manila_ui_plugin_for_horizon"
|
||||
MANILA_VERSION = "2.50"
|
||||
MANILA_VERSION = "2.51"
|
||||
MANILA_SERVICE_TYPE = "sharev2"
|
||||
|
||||
# API static values
|
||||
@ -302,10 +302,11 @@ def share_network_list(request, detailed=False, search_opts=None):
|
||||
|
||||
|
||||
def share_network_create(request, neutron_net_id=None, neutron_subnet_id=None,
|
||||
name=None, description=None):
|
||||
name=None, description=None, availability_zone=None):
|
||||
return manilaclient(request).share_networks.create(
|
||||
neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id,
|
||||
name=name, description=description)
|
||||
name=name, description=description,
|
||||
availability_zone=availability_zone)
|
||||
|
||||
|
||||
def share_network_get(request, share_net_id):
|
||||
|
@ -1,24 +0,0 @@
|
||||
# Copyright (c) 2015 Mirantis, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
|
||||
def network_list(request):
|
||||
return neutron.network_list(request)
|
||||
|
||||
|
||||
def network_get(request, net_id):
|
||||
return neutron.network_get(request, net_id)
|
@ -21,14 +21,6 @@ class ShareNetworksTable(tables.DataTable):
|
||||
"name", verbose_name=_("Name"),
|
||||
link="horizon:admin:share_networks:share_network_detail")
|
||||
project = tables.Column("project_name", verbose_name=_("Project"))
|
||||
neutron_net = tables.Column("neutron_net", verbose_name=_("Neutron Net"))
|
||||
neutron_subnet = tables.Column(
|
||||
"neutron_subnet", verbose_name=_("Neutron Subnet"))
|
||||
ip_version = tables.Column("ip_version", verbose_name=_("IP Version"))
|
||||
network_type = tables.Column(
|
||||
"network_type", verbose_name=_("Network Type"))
|
||||
segmentation_id = tables.Column(
|
||||
"segmentation_id", verbose_name=_("Segmentation Id"))
|
||||
|
||||
def get_object_display(self, share_network):
|
||||
return share_network.name or str(share_network.id)
|
||||
|
@ -1,53 +1,90 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
|
||||
<h3>{% trans "Share Network Overview" %}</h3>
|
||||
<div class="detail">
|
||||
<hr class="header_rule">
|
||||
<div class="row">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ share_network.name }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ share_network.id }}</dd>
|
||||
{% if share_network.description %}
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ share_network.description }}</dd>
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ share_network.description }}</dd>
|
||||
{% endif %}
|
||||
{% if share_network.share_servers %}
|
||||
<dt>{% trans "Share Servers" %}</dt>
|
||||
{% for server in share_network.share_servers %}
|
||||
{% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
|
||||
<dd><a href="{{ server_url }}">{{ server.id }}</a></dd>
|
||||
{% endfor %}
|
||||
{% if share_network.created_at %}
|
||||
<dt>{% trans "Created At" %}</dt>
|
||||
<dd>{{ share_network.created_at }}</dd>
|
||||
{% endif %}
|
||||
{% if share_network.updated_at %}
|
||||
<dt>{% trans "Updated At" %} </dt>
|
||||
<dd>{{ share_network.updated_at }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Share Network ID" %}</dt>
|
||||
<dd>{{ share_network.id }}</dd>
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dd>{{ share_network.project_id }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="detail">
|
||||
<h4>{% trans "Net Details" %}</h4>
|
||||
<h4>{% trans "Subnets" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Network" %}</dt>
|
||||
{% if share_network.neutron_net %}
|
||||
<dd>{{ share_network.neutron_net }}</dd>
|
||||
<dt>{% trans "Subnet" %}</dt>
|
||||
<dd>{{ share_network.neutron_subnet}}</dd>
|
||||
{% endif %}
|
||||
<dl class="dl-horizontal">
|
||||
{% for subnet in share_network.share_network_subnets %}
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Id" %}</dt>
|
||||
<dd>
|
||||
{{subnet.id}}
|
||||
</dd>
|
||||
{% if subnet.neutron_net != "Unknown" %}
|
||||
{% url 'horizon:admin:networks:detail' subnet.neutron_net_id as network_detail_url %}
|
||||
<dt>{% trans "Neutron Network" %}</dt>
|
||||
<dd>
|
||||
<a href="{{ network_detail_url }}">{{subnet.neutron_net}}</a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
{% if subnet.neutron_subnet != "Unknown" %}
|
||||
{% url 'horizon:admin:networks:subnets:detail' subnet.neutron_subnet_id as subnet_detail_url %}
|
||||
<dt>{% trans "Neutron Subnet" %}</dt>
|
||||
<dd>
|
||||
<a href="{{ subnet_detail_url }}">{{subnet.neutron_subnet}}</a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Availability Zone" %}</dt>
|
||||
<dd>
|
||||
{{subnet.availability_zone}}
|
||||
</dd>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="detail">
|
||||
<h4>{% trans "Security Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
{% for sec_service in share_network.sec_services %}
|
||||
{% url 'horizon:admin:security_services:security_service_detail' sec_service.id as sec_service_url%}
|
||||
<dl class="dl-horizontal">
|
||||
{% if share_network.share_servers %}
|
||||
<div class="detail">
|
||||
<h4>{% trans "Share Servers" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% for server in share_network.share_servers %}
|
||||
<ul>
|
||||
{% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
|
||||
<li><a href="{{ server_url }}">{{server.id }}</a></li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if share_network.sec_services %}
|
||||
<div class="detail">
|
||||
<h4>{% trans "Security Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
{% for sec_service in share_network.sec_services %}
|
||||
{% url 'horizon:admin:security_services:security_service_detail' sec_service.id as sec_service_url%}
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Id" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.id }}</a></dd>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.name }}</a></dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ sec_service.type }}</dd>
|
||||
</dl>
|
||||
<br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
</dl>
|
||||
<br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -21,8 +21,6 @@ from django.utils.translation import gettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import tables
|
||||
from horizon.utils import memoized
|
||||
from openstack_dashboard.api import base
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
from manila_ui.api import manila
|
||||
from manila_ui.dashboards.admin.share_networks import tables as sn_tables
|
||||
@ -42,19 +40,7 @@ class ShareNetworksView(tables.MultiTableView):
|
||||
def get_share_networks_data(self):
|
||||
try:
|
||||
share_networks = manila.share_network_list(
|
||||
self.request, detailed=True, search_opts={'all_tenants': True})
|
||||
if base.is_service_enabled(self.request, 'network'):
|
||||
neutron_net_names = dict(
|
||||
(net.id, net.name)
|
||||
for net in neutron.network_list(self.request))
|
||||
neutron_subnet_names = dict(
|
||||
(net.id, net.name)
|
||||
for net in neutron.subnet_list(self.request))
|
||||
for sn in share_networks:
|
||||
sn.neutron_net = neutron_net_names.get(
|
||||
sn.neutron_net_id) or sn.neutron_net_id or "-"
|
||||
sn.neutron_subnet = neutron_subnet_names.get(
|
||||
sn.neutron_subnet_id) or sn.neutron_subnet_id or "-"
|
||||
self.request, detailed=True, search_opts={"all_tenants": True})
|
||||
except Exception:
|
||||
share_networks = []
|
||||
exceptions.handle(
|
||||
|
@ -22,7 +22,6 @@ from openstack_dashboard.api import base
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
from manila_ui.api import manila
|
||||
from manila_ui.api import network
|
||||
from manila_ui.dashboards import utils
|
||||
|
||||
|
||||
@ -34,8 +33,8 @@ class Create(forms.SelfHandlingForm):
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(Create, self).__init__(request, *args, **kwargs)
|
||||
self.neutron_enabled = base.is_service_enabled(request, 'network')
|
||||
net_choices = network.network_list(request)
|
||||
if self.neutron_enabled:
|
||||
net_choices = neutron.network_list(request)
|
||||
self.fields['neutron_net_id'] = forms.ChoiceField(
|
||||
choices=[(' ', ' ')] +
|
||||
[(utils.transform_dashed_name(choice.id),
|
||||
|
@ -109,14 +109,8 @@ class ShareNetworksTable(tables.DataTable):
|
||||
name = tables.WrappingColumn(
|
||||
"name", verbose_name=_("Name"),
|
||||
link="horizon:project:share_networks:share_network_detail")
|
||||
neutron_net = tables.Column("neutron_net", verbose_name=_("Neutron Net"))
|
||||
neutron_subnet = tables.Column(
|
||||
"neutron_subnet", verbose_name=_("Neutron Subnet"))
|
||||
ip_version = tables.Column("ip_version", verbose_name=_("IP Version"))
|
||||
network_type = tables.Column(
|
||||
"network_type", verbose_name=_("Network Type"))
|
||||
segmentation_id = tables.Column(
|
||||
"segmentation_id", verbose_name=_("Segmentation Id"))
|
||||
description = tables.WrappingColumn(
|
||||
"description", verbose_name=_("Description"))
|
||||
|
||||
def get_object_display(self, share_network):
|
||||
return share_network.name or str(share_network.id)
|
||||
|
@ -1,65 +1,90 @@
|
||||
{% load i18n sizeformat parse_date %}
|
||||
|
||||
<h3>{% trans "Share Network Overview" %}</h3>
|
||||
<div class="detail">
|
||||
<hr class="header_rule">
|
||||
<div class="row">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd>{{ share_network.name }}</dd>
|
||||
<dt>{% trans "ID" %}</dt>
|
||||
<dd>{{ share_network.id }}</dd>
|
||||
{% if share_network.description %}
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ share_network.description }}</dd>
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ share_network.description }}</dd>
|
||||
{% endif %}
|
||||
{% if share_network.created_at %}
|
||||
<dt>{% trans "Created At" %}</dt>
|
||||
<dd>{{ share_network.created_at }}</dd>
|
||||
{% endif %}
|
||||
{% if share_network.updated_at %}
|
||||
<dt>{% trans "Updated At" %} </dt>
|
||||
<dd>{{ share_network.updated_at }}</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Share Network ID" %}</dt>
|
||||
<dd>{{ share_network.id }}</dd>
|
||||
<dt>{% trans "Project ID" %}</dt>
|
||||
<dd>{{ share_network.project_id }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="detail">
|
||||
<h4>{% trans "Network Details" %}</h4>
|
||||
<h4>{% trans "Subnets" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Network" %}</dt>
|
||||
{% if share_network.neutron_net %}
|
||||
<dd>{{ share_network.neutron_net }}</dd>
|
||||
<dt>{% trans "Subnet" %}</dt>
|
||||
<dd>{{ share_network.neutron_subnet}}</dd>
|
||||
{% endif %}
|
||||
<dl class="dl-horizontal">
|
||||
{% for subnet in share_network.share_network_subnets %}
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Id" %}</dt>
|
||||
<dd>
|
||||
{{subnet.id}}
|
||||
</dd>
|
||||
{% if subnet.neutron_net != "Unknown" %}
|
||||
{% url 'horizon:project:networks:detail' subnet.neutron_net_id as network_detail_url %}
|
||||
<dt>{% trans "Neutron Network" %}</dt>
|
||||
<dd>
|
||||
<a href="{{ network_detail_url }}">{{subnet.neutron_net}}</a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
{% if subnet.neutron_subnet != "Unknown" %}
|
||||
{% url 'horizon:project:networks:subnets:detail' subnet.neutron_subnet_id as subnet_detail_url %}
|
||||
<dt>{% trans "Neutron Subnet" %}</dt>
|
||||
<dd>
|
||||
<a href="{{ subnet_detail_url }}">{{subnet.neutron_subnet}}</a>
|
||||
</dd>
|
||||
{% endif %}
|
||||
<dt>{% trans "Availability Zone" %}</dt>
|
||||
<dd>
|
||||
{{subnet.availability_zone}}
|
||||
</dd>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
||||
{% if share_network.share_servers %}
|
||||
<div class="detail">
|
||||
<h4>{% trans "Share Servers" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% for server in share_network.share_servers %}
|
||||
<ul>
|
||||
{% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
|
||||
<li><a href="{{ server_url }}">{{ server.id }}</a></li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<h4>{% trans "Share Servers" %}</h4>
|
||||
<hr class="header_rule">
|
||||
<dl class="dl-horizontal">
|
||||
{% for server in share_network.share_servers %}
|
||||
<ul>
|
||||
{% url 'horizon:admin:share_servers:share_server_detail' server.id as server_url %}
|
||||
<li><a href="{{ server_url }}">{{server.id }}</a></li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if share_network.sec_services %}
|
||||
<div class="detail">
|
||||
<h4>{% trans "Security Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
{% for sec_service in share_network.sec_services %}
|
||||
{% url 'horizon:project:security_services:security_service_detail' sec_service.id as sec_service_url%}
|
||||
<div class="detail">
|
||||
<h4>{% trans "Security Services" %}</h4>
|
||||
<hr class="header_rule">
|
||||
{% for sec_service in share_network.sec_services %}
|
||||
{% url 'horizon:project:security_services:security_service_detail' sec_service.id as sec_service_url%}
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Id" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.id }}</a></dd>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.name }}</a></dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ sec_service.type }}</dd>
|
||||
<dt>{% trans "Id" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.id }}</a></dd>
|
||||
<dt>{% trans "Name" %}</dt>
|
||||
<dd><a href="{{ sec_service_url }}">{{ sec_service.name }}</a></dd>
|
||||
<dt>{% trans "Type" %}</dt>
|
||||
<dd>{{ sec_service.type }}</dd>
|
||||
</dl>
|
||||
<br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -15,7 +15,6 @@
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import tables
|
||||
from horizon import tabs
|
||||
from horizon.utils import memoized
|
||||
@ -24,7 +23,6 @@ from openstack_dashboard.api import base
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
from manila_ui.api import manila
|
||||
from manila_ui.dashboards.project.share_networks import forms as sn_forms
|
||||
from manila_ui.dashboards.project.share_networks import tables as sn_tables
|
||||
from manila_ui.dashboards.project.share_networks import tabs as sn_tabs
|
||||
import manila_ui.dashboards.project.share_networks.workflows as sn_workflows
|
||||
@ -43,16 +41,6 @@ class ShareNetworksView(tables.MultiTableView):
|
||||
try:
|
||||
share_networks = manila.share_network_list(
|
||||
self.request, detailed=True)
|
||||
if base.is_service_enabled(self.request, 'network'):
|
||||
neutron_net_names = dict((net.id, net.name) for net in
|
||||
neutron.network_list(self.request))
|
||||
neutron_subnet_names = dict((net.id, net.name) for net in
|
||||
neutron.subnet_list(self.request))
|
||||
for sn in share_networks:
|
||||
sn.neutron_net = neutron_net_names.get(
|
||||
sn.neutron_net_id) or sn.neutron_net_id or "-"
|
||||
sn.neutron_subnet = neutron_subnet_names.get(
|
||||
sn.neutron_subnet_id) or sn.neutron_subnet_id or "-"
|
||||
except Exception:
|
||||
share_networks = []
|
||||
exceptions.handle(
|
||||
@ -75,13 +63,9 @@ class Update(workflows.WorkflowView):
|
||||
return context
|
||||
|
||||
|
||||
class Create(forms.ModalFormView):
|
||||
form_class = sn_forms.Create
|
||||
class Create(workflows.WorkflowView):
|
||||
workflow_class = sn_workflows.CreateShareNetworkWorkflow
|
||||
form_id = "create_share_network"
|
||||
template_name = 'project/share_networks/create.html'
|
||||
modal_header = _("Create Share Network")
|
||||
modal_id = "create_share_network_modal"
|
||||
submit_label = _("Create")
|
||||
submit_url = reverse_lazy(
|
||||
"horizon:project:share_networks:share_network_create")
|
||||
success_url = reverse_lazy("horizon:project:share_networks:index")
|
||||
@ -110,19 +94,32 @@ class Detail(tabs.TabView):
|
||||
share_net_id = self.kwargs['share_network_id']
|
||||
share_net = manila.share_network_get(self.request, share_net_id)
|
||||
if base.is_service_enabled(self.request, 'network'):
|
||||
try:
|
||||
share_net.neutron_net = neutron.network_get(
|
||||
self.request, share_net.neutron_net_id).name_or_id
|
||||
except (
|
||||
neutron.neutron_client.exceptions.NeutronClientException):
|
||||
share_net.neutron_net = _("Unknown")
|
||||
try:
|
||||
share_net.neutron_subnet = neutron.subnet_get(
|
||||
self.request, share_net.neutron_subnet_id).name_or_id
|
||||
except (
|
||||
neutron.neutron_client.exceptions.NeutronClientException):
|
||||
share_net.neutron_subnet = _("Unknown")
|
||||
|
||||
for subnet in share_net.share_network_subnets:
|
||||
# Neutron Net ID
|
||||
try:
|
||||
subnet["neutron_net"] = neutron.network_get(
|
||||
self.request, subnet["neutron_net_id"]).name_or_id
|
||||
except (
|
||||
neutron.neutron_client.exceptions
|
||||
.NeutronClientException
|
||||
):
|
||||
subnet["neutron_net"] = _("Unknown")
|
||||
# Neutron Subnet ID
|
||||
try:
|
||||
subnet["neutron_subnet"] = neutron.subnet_get(
|
||||
self.request,
|
||||
subnet["neutron_subnet_id"]).name_or_id
|
||||
except (
|
||||
neutron.neutron_client.exceptions
|
||||
.NeutronClientException
|
||||
):
|
||||
subnet["neutron_subnet"] = _("Unknown")
|
||||
# List all azs if availability_zone is None
|
||||
availability_zones = manila.availability_zone_list(self.request)
|
||||
az_list = ", ".join([az.name for az in availability_zones])
|
||||
for subnet in share_net.share_network_subnets:
|
||||
if subnet["availability_zone"] is None:
|
||||
subnet["availability_zone"] = az_list
|
||||
share_net.sec_services = (
|
||||
manila.share_network_security_service_list(
|
||||
self.request, share_net_id))
|
||||
|
@ -12,12 +12,160 @@
|
||||
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from horizon import exceptions
|
||||
from horizon import forms
|
||||
from horizon import messages
|
||||
from horizon import workflows
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.api import base
|
||||
|
||||
from manila_ui.api import manila
|
||||
from manila_ui.dashboards import utils
|
||||
|
||||
|
||||
class CreateShareNetworkInfoAction(workflows.Action):
|
||||
share_network_name = forms.CharField(
|
||||
max_length=255, label=_("Name"), required=True)
|
||||
share_network_description = forms.CharField(
|
||||
widget=forms.Textarea, label=_("Description"), required=False)
|
||||
|
||||
class Meta(object):
|
||||
name = ("Share Network")
|
||||
|
||||
|
||||
class CreateShareNetworkInfoStep(workflows.Step):
|
||||
action_class = CreateShareNetworkInfoAction
|
||||
contributes = ("share_network_description",
|
||||
"share_network_name")
|
||||
|
||||
|
||||
class AddShareNetworkSubnetAction(workflows.MembershipAction):
|
||||
|
||||
availability_zone = forms.ChoiceField(
|
||||
required=False,
|
||||
label=_('Availability Zone'),
|
||||
widget=forms.ThemableSelectWidget(attrs={
|
||||
'data-availability_zone': _('Availability Zone')}))
|
||||
|
||||
neutron_net_id = forms.ChoiceField(
|
||||
required=False,
|
||||
label=_('Neutron Net'),
|
||||
widget=forms.ThemableSelectWidget(attrs={
|
||||
'class': 'switchable',
|
||||
'data-slug': 'neutron_net_id',
|
||||
'data-neutron_net_id': _('Neutron Net')}))
|
||||
|
||||
class Meta(object):
|
||||
name = _("Subnet")
|
||||
help_text = _("Specify an Availability Zone or an existing subnet. "
|
||||
"If no details are specified, "
|
||||
"then a default subnet with a null Availability "
|
||||
"Zone will be created automatically.")
|
||||
|
||||
def __init__(self, request, context, *args, **kwargs):
|
||||
super().__init__(request, context, *args, **kwargs)
|
||||
|
||||
self.fields['availability_zone'].choices = (
|
||||
self.get_availability_zone_choices(request)
|
||||
)
|
||||
self.neutron_enabled = base.is_service_enabled(request, 'network')
|
||||
if self.neutron_enabled:
|
||||
try:
|
||||
self.fields['neutron_net_id'].choices, networks = (
|
||||
self.get_neutron_net_id_choices(request)
|
||||
)
|
||||
except Exception:
|
||||
msg = _('Unable to initialize neutron networks.')
|
||||
exceptions.handle(request, msg)
|
||||
try:
|
||||
self.get_neutron_subnet_id_choices(request, networks)
|
||||
except Exception:
|
||||
msg = _('Unable to initialize neutron subnets.')
|
||||
exceptions.handle(request, msg)
|
||||
|
||||
def get_availability_zone_choices(self, request):
|
||||
availability_zone_choices = [('', _('None'))]
|
||||
|
||||
for availability_zone in manila.availability_zone_list(request):
|
||||
availability_zone_choices.append(
|
||||
(availability_zone.id, availability_zone.name)
|
||||
)
|
||||
return availability_zone_choices
|
||||
|
||||
def get_neutron_net_id_choices(self, request):
|
||||
net_choices = [('', _('None'))]
|
||||
|
||||
networks = api.neutron.network_list(request)
|
||||
for network in networks:
|
||||
net_choices.append((utils.transform_dashed_name(network.id),
|
||||
network.name_or_id))
|
||||
return net_choices, networks
|
||||
|
||||
def get_neutron_subnet_id_choices(self, request, networks):
|
||||
for net in networks:
|
||||
subnet_field_name = (
|
||||
'subnet-choices-%s' % utils.transform_dashed_name(net.id))
|
||||
data_net_id = (
|
||||
'data-neutron_net_id-%s' % utils.transform_dashed_name(net.id))
|
||||
subnet_field = forms.ChoiceField(
|
||||
required=False,
|
||||
choices=(),
|
||||
label=_('Neutron Subnet'),
|
||||
widget=forms.ThemableSelectWidget(attrs={
|
||||
'class': 'switched',
|
||||
'data-switch-on': 'neutron_net_id',
|
||||
data_net_id: _('Neutron Subnet')}))
|
||||
self.fields[subnet_field_name] = subnet_field
|
||||
subnet_choices = api.neutron.subnet_list(request,
|
||||
network_id=net.id)
|
||||
self.fields[subnet_field_name].choices = [
|
||||
(choice.id, choice.name_or_id)
|
||||
for choice in subnet_choices]
|
||||
|
||||
def hide_neutron_subnet_id_choices(self):
|
||||
self.fields['neutron_subnet_id'].choices = []
|
||||
self.fields['neutron_subnet_id'].widget = forms.HiddenInput()
|
||||
|
||||
|
||||
class AddShareNetworkSubnetStep(workflows.Step):
|
||||
action_class = AddShareNetworkSubnetAction
|
||||
contributes = ("neutron_net_id", "neutron_subnet_id", "availability_zone")
|
||||
|
||||
|
||||
class CreateShareNetworkWorkflow(workflows.Workflow):
|
||||
slug = "create_share_network"
|
||||
name = _("Create Share Network")
|
||||
finalize_button_name = _("Create Share Network")
|
||||
success_message = _('Created share network "%s".')
|
||||
failure_message = _('Unable to create share network "%s".')
|
||||
success_url = 'horizon:project:share_networks:index'
|
||||
default_steps = (CreateShareNetworkInfoStep, AddShareNetworkSubnetStep)
|
||||
wizard = True
|
||||
|
||||
def handle(self, request, context):
|
||||
try:
|
||||
data = request.POST
|
||||
send_data = {'name': context['share_network_name']}
|
||||
if context['share_network_description']:
|
||||
send_data['description'] = context['share_network_description']
|
||||
neutron_net_id = context.get('neutron_net_id')
|
||||
if neutron_net_id:
|
||||
send_data['neutron_net_id'] = utils.transform_dashed_name(
|
||||
neutron_net_id.strip())
|
||||
subnet_key = (
|
||||
'subnet-choices-%s' % neutron_net_id.strip()
|
||||
)
|
||||
if data.get(subnet_key) is not None:
|
||||
send_data['neutron_subnet_id'] = data.get(subnet_key)
|
||||
if context['availability_zone']:
|
||||
send_data['availability_zone'] = context['availability_zone']
|
||||
share_network = manila.share_network_create(request, **send_data)
|
||||
messages.success(request, _('Successfully created share'
|
||||
' network: %s') % send_data['name'])
|
||||
return share_network
|
||||
except Exception:
|
||||
exceptions.handle(request, _('Unable to create share network.'))
|
||||
return False
|
||||
|
||||
|
||||
class UpdateShareNetworkInfoAction(workflows.Action):
|
||||
|
@ -412,6 +412,7 @@ class ManilaApiTests(base.APITestCase):
|
||||
"description": None,
|
||||
"neutron_net_id": None,
|
||||
"neutron_subnet_id": None,
|
||||
"availability_zone": None
|
||||
}
|
||||
expected_kwargs.update(**kwargs)
|
||||
|
||||
|
@ -18,6 +18,7 @@ from horizon import exceptions as horizon_exceptions
|
||||
from neutronclient.client import exceptions
|
||||
from openstack_dashboard.api import keystone as api_keystone
|
||||
from openstack_dashboard.api import neutron as api_neutron
|
||||
from oslo_utils import timeutils
|
||||
from unittest import mock
|
||||
|
||||
from manila_ui.api import manila as api_manila
|
||||
@ -39,8 +40,15 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
# Reset taken list of projects to avoid test interference
|
||||
utils.PROJECTS = {}
|
||||
|
||||
class FakeAZ(object):
|
||||
def __init__(self, name, id):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.created_at = timeutils.utcnow()
|
||||
|
||||
def test_detail_view(self):
|
||||
share_net = test_data.active_share_network
|
||||
share_network_subnets = share_net.share_network_subnets
|
||||
sec_service = test_data.sec_service
|
||||
self.mock_object(
|
||||
api_manila, "share_server_list", mock.Mock(return_value=[]))
|
||||
@ -55,6 +63,10 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
api_neutron, "network_get", mock.Mock(return_value=network))
|
||||
self.mock_object(
|
||||
api_neutron, "subnet_get", mock.Mock(return_value=subnet))
|
||||
self.mock_object(
|
||||
api_manila, "availability_zone_list",
|
||||
mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')])
|
||||
)
|
||||
url = reverse('horizon:admin:share_networks:share_network_detail',
|
||||
args=[share_net.id])
|
||||
|
||||
@ -65,11 +77,23 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.name, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.id, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % network.name_or_id, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % subnet.name_or_id, 1, 200)
|
||||
for sub in share_network_subnets:
|
||||
self.assertContains(res, "<a href=\"/admin/networks"
|
||||
"/%s/detail\">%s</a>" % (
|
||||
sub['neutron_net_id'],
|
||||
network.name), 1, 200)
|
||||
self.assertContains(res, "<a href=\"/admin/security_services"
|
||||
"/%s\">%s</a>" % (sec_service.id,
|
||||
sec_service.name), 1, 200)
|
||||
network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id']
|
||||
) for sub in share_network_subnets]
|
||||
subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id']
|
||||
) for sub in share_network_subnets]
|
||||
|
||||
api_neutron.network_get.assert_has_calls(network_get_calls,
|
||||
any_order=True)
|
||||
api_neutron.subnet_get.assert_has_calls(subnet_get_calls,
|
||||
any_order=True)
|
||||
self.assertNoMessages()
|
||||
api_manila.share_network_security_service_list.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
@ -77,14 +101,11 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
mock.ANY, search_opts={'share_network_id': share_net.id})
|
||||
api_manila.share_network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
api_neutron.network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_net_id)
|
||||
api_neutron.subnet_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_subnet_id)
|
||||
|
||||
def test_detail_view_network_not_found(self):
|
||||
share_net = test_data.active_share_network
|
||||
sec_service = test_data.sec_service
|
||||
share_network_subnets = share_net.share_network_subnets
|
||||
url = reverse('horizon:admin:share_networks:share_network_detail',
|
||||
args=[share_net.id])
|
||||
self.mock_object(
|
||||
@ -100,7 +121,10 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
self.mock_object(
|
||||
api_neutron, "subnet_get", mock.Mock(
|
||||
side_effect=exceptions.NeutronClientException('fake', 500)))
|
||||
|
||||
self.mock_object(
|
||||
api_manila, "availability_zone_list",
|
||||
mock.Mock(return_value=[])
|
||||
)
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertContains(res, "<h1>Share Network Details: %s</h1>"
|
||||
@ -108,10 +132,19 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.name, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.id, 1, 200)
|
||||
self.assertContains(res, "<dd>Unknown</dd>", 2, 200)
|
||||
self.assertNotContains(res, "<dd>%s</dd>" % share_net.neutron_net_id)
|
||||
self.assertNotContains(res,
|
||||
"<dd>%s</dd>" % share_net.neutron_subnet_id)
|
||||
for sub in share_network_subnets:
|
||||
self.assertNotContains(res, "<dd>%s</dd>" % sub['neutron_net_id'])
|
||||
self.assertNotContains(res,
|
||||
"<dd>%s</dd>" % sub['neutron_subnet_id'])
|
||||
network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id']
|
||||
) for sub in share_network_subnets]
|
||||
subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id']
|
||||
) for sub in share_network_subnets]
|
||||
|
||||
api_neutron.network_get.assert_has_calls(network_get_calls,
|
||||
any_order=True)
|
||||
api_neutron.subnet_get.assert_has_calls(subnet_get_calls,
|
||||
any_order=True)
|
||||
self.assertContains(res, "<a href=\"/admin/security_services"
|
||||
"/%s\">%s</a>" % (sec_service.id,
|
||||
sec_service.name), 1, 200)
|
||||
@ -122,10 +155,6 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
mock.ANY, search_opts={'share_network_id': share_net.id})
|
||||
api_manila.share_network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
api_neutron.network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_net_id)
|
||||
api_neutron.subnet_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_subnet_id)
|
||||
|
||||
def test_detail_view_with_exception(self):
|
||||
url = reverse('horizon:admin:share_networks:share_network_detail',
|
||||
@ -143,10 +172,6 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
def test_delete_share_network(self):
|
||||
share_network = test_data.inactive_share_network
|
||||
formData = {'action': 'share_networks__delete__%s' % share_network.id}
|
||||
self.mock_object(
|
||||
api_neutron, "network_list", mock.Mock(return_value=[]))
|
||||
self.mock_object(
|
||||
api_neutron, "subnet_list", mock.Mock(return_value=[]))
|
||||
self.mock_object(api_manila, "share_network_delete")
|
||||
self.mock_object(
|
||||
api_manila, "share_network_list",
|
||||
@ -156,11 +181,9 @@ class ShareNetworksTests(test.BaseAdminViewTests):
|
||||
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
api_keystone.tenant_list.assert_called_once_with(mock.ANY)
|
||||
api_manila.share_network_delete.assert_called_once_with(
|
||||
mock.ANY, test_data.inactive_share_network.id)
|
||||
mock.ANY, share_network.id)
|
||||
api_manila.share_network_list.assert_called_once_with(
|
||||
mock.ANY, detailed=True, search_opts={'all_tenants': True})
|
||||
api_neutron.network_list.assert_called_once_with(mock.ANY)
|
||||
api_neutron.subnet_list.assert_called_once_with(mock.ANY)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
@ -16,10 +16,10 @@ from django.urls import reverse
|
||||
from neutronclient.client import exceptions
|
||||
from openstack_auth import policy
|
||||
from openstack_dashboard import api
|
||||
from oslo_utils import timeutils
|
||||
from unittest import mock
|
||||
|
||||
from manila_ui.api import manila as api_manila
|
||||
from manila_ui.api import network as api_manila_network
|
||||
from manila_ui.dashboards import utils
|
||||
from manila_ui.tests.dashboards.project import test_data
|
||||
from manila_ui.tests import helpers as test
|
||||
@ -28,40 +28,55 @@ INDEX_URL = reverse('horizon:project:share_networks:index')
|
||||
|
||||
|
||||
class ShareNetworksViewTests(test.TestCase):
|
||||
class FakeAZ(object):
|
||||
def __init__(self, name, id):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.created_at = timeutils.utcnow()
|
||||
|
||||
def test_create_share_network(self):
|
||||
share_net = test_data.active_share_network
|
||||
|
||||
url = reverse('horizon:project:share_networks:share_network_create')
|
||||
neutron_net_id = self.networks.first().id
|
||||
sanitized_net_id = utils.transform_dashed_name(neutron_net_id)
|
||||
formData = {
|
||||
'name': 'new_share_network',
|
||||
'description': 'This is test share network',
|
||||
'share_network_name': 'new_share_network',
|
||||
'share_network_description': 'This is test share network',
|
||||
'method': 'CreateForm',
|
||||
'neutron_net_id': utils.transform_dashed_name(neutron_net_id),
|
||||
'availability_zone': 'fake_az',
|
||||
f'subnet-choices-{sanitized_net_id}':
|
||||
self.networks.first().subnets[0].id,
|
||||
}
|
||||
for net in self.networks.list():
|
||||
sanitized_net_id = utils.transform_dashed_name(net.id)
|
||||
subnet_choices_field = 'subnet-choices-%s' % sanitized_net_id
|
||||
formData[subnet_choices_field] = net.subnets[0].id
|
||||
|
||||
self.mock_object(
|
||||
api.neutron, "subnet_list",
|
||||
mock.Mock(return_value=self.subnets.list()))
|
||||
self.mock_object(
|
||||
api_manila_network, "network_list",
|
||||
api.neutron, "network_list",
|
||||
mock.Mock(return_value=self.networks.list()))
|
||||
self.mock_object(
|
||||
api_manila, "share_network_create",
|
||||
mock.Mock(return_value=share_net))
|
||||
self.mock_object(
|
||||
api_manila, "availability_zone_list",
|
||||
mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')])
|
||||
)
|
||||
|
||||
self.client.post(url, formData)
|
||||
res = self.client.post(url, formData)
|
||||
|
||||
sanitized_neutron_net_field = formData[
|
||||
'subnet-choices-%s' % utils.transform_dashed_name(neutron_net_id)]
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(error=0, warning=0)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
api_manila.share_network_create.assert_called_once_with(
|
||||
mock.ANY, name=formData['name'], neutron_net_id=neutron_net_id,
|
||||
neutron_subnet_id=sanitized_neutron_net_field,
|
||||
description=formData['description'])
|
||||
api_manila_network.network_list.assert_called_once_with(mock.ANY)
|
||||
mock.ANY, name=formData['share_network_name'],
|
||||
neutron_net_id=neutron_net_id,
|
||||
neutron_subnet_id=self.networks.first().subnets[0].id,
|
||||
description=formData['share_network_description'],
|
||||
availability_zone='fake_az')
|
||||
api_manila.availability_zone_list.assert_called_once_with(mock.ANY)
|
||||
api.neutron.network_list.assert_called_once_with(mock.ANY)
|
||||
api.neutron.subnet_list.assert_has_calls([
|
||||
mock.call(mock.ANY, network_id=network.id)
|
||||
for network in self.networks.list()
|
||||
@ -75,12 +90,6 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
api_manila, "share_network_list",
|
||||
mock.Mock(return_value=[
|
||||
test_data.active_share_network, share_network]))
|
||||
self.mock_object(
|
||||
api.neutron, "network_list",
|
||||
mock.Mock(return_value=self.networks.list()))
|
||||
self.mock_object(
|
||||
api.neutron, "subnet_list",
|
||||
mock.Mock(return_value=self.subnets.list()))
|
||||
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
|
||||
@ -89,12 +98,11 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
mock.ANY, detailed=True)
|
||||
api_manila.share_network_delete.assert_called_once_with(
|
||||
mock.ANY, share_network.id)
|
||||
api.neutron.network_list.assert_called_once_with(mock.ANY)
|
||||
api.neutron.subnet_list.assert_called_once_with(mock.ANY)
|
||||
|
||||
def test_detail_view(self):
|
||||
share_net = test_data.active_share_network
|
||||
sec_service = test_data.sec_service
|
||||
share_network_subnets = share_net.share_network_subnets
|
||||
self.mock_object(
|
||||
api_manila, "share_server_list", mock.Mock(return_value=[]))
|
||||
self.mock_object(
|
||||
@ -104,40 +112,58 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
mock.Mock(return_value=[sec_service]))
|
||||
network = self.networks.first()
|
||||
subnet = self.subnets.first()
|
||||
|
||||
self.mock_object(
|
||||
api.neutron, "network_get", mock.Mock(return_value=network))
|
||||
self.mock_object(
|
||||
api.neutron, "subnet_get", mock.Mock(return_value=subnet))
|
||||
self.mock_object(
|
||||
api_manila, "availability_zone_list",
|
||||
mock.Mock(return_value=[self.FakeAZ('fake_az', 'fake_az')])
|
||||
)
|
||||
url = reverse('horizon:project:share_networks:share_network_detail',
|
||||
args=[share_net.id])
|
||||
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertNoMessages()
|
||||
self.assertContains(res, "<h1>Share Network Details: %s</h1>"
|
||||
% share_net.name,
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.name, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.id, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % network.name_or_id, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % subnet.name_or_id, 1, 200)
|
||||
for sub in share_network_subnets:
|
||||
self.assertContains(res, "<a href=\"/project/networks"
|
||||
"/%s/detail\">%s</a>" % (
|
||||
sub['neutron_net_id'],
|
||||
network.name), 1, 200)
|
||||
self.assertContains(res, "<a href=\"/project/networks/subnets"
|
||||
"/%s/detail\">%s</a>" % (
|
||||
sub['neutron_subnet_id'],
|
||||
subnet['name']), 1, 200)
|
||||
network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id'])
|
||||
for sub in share_network_subnets]
|
||||
subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id'])
|
||||
for sub in share_network_subnets]
|
||||
|
||||
api.neutron.network_get.assert_has_calls(network_get_calls,
|
||||
any_order=True)
|
||||
api.neutron.subnet_get.assert_has_calls(subnet_get_calls,
|
||||
any_order=True)
|
||||
self.assertContains(res, "<a href=\"/project/security_services"
|
||||
"/%s\">%s</a>" % (sec_service.id,
|
||||
sec_service.name), 1, 200)
|
||||
self.assertNoMessages()
|
||||
api_manila.share_network_security_service_list.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
api_manila.share_server_list.assert_called_once_with(
|
||||
mock.ANY, search_opts={'share_network_id': share_net.id})
|
||||
api_manila.share_network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
api.neutron.network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_net_id)
|
||||
api.neutron.subnet_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_subnet_id)
|
||||
|
||||
def test_detail_view_network_not_found(self):
|
||||
share_net = test_data.active_share_network
|
||||
sec_service = test_data.sec_service
|
||||
share_network_subnets = share_net.share_network_subnets
|
||||
url = reverse('horizon:project:share_networks:share_network_detail',
|
||||
args=[share_net.id])
|
||||
self.mock_object(
|
||||
@ -153,7 +179,10 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
self.mock_object(
|
||||
api.neutron, "subnet_get", mock.Mock(
|
||||
side_effect=exceptions.NeutronClientException('fake', 500)))
|
||||
|
||||
self.mock_object(
|
||||
api_manila, "availability_zone_list",
|
||||
mock.Mock(return_value=[])
|
||||
)
|
||||
res = self.client.get(url)
|
||||
|
||||
self.assertContains(res, "<h1>Share Network Details: %s</h1>"
|
||||
@ -161,10 +190,19 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.name, 1, 200)
|
||||
self.assertContains(res, "<dd>%s</dd>" % share_net.id, 1, 200)
|
||||
self.assertContains(res, "<dd>Unknown</dd>", 2, 200)
|
||||
self.assertNotContains(res, "<dd>%s</dd>" % share_net.neutron_net_id)
|
||||
self.assertNotContains(res,
|
||||
"<dd>%s</dd>" % share_net.neutron_subnet_id)
|
||||
for sub in share_network_subnets:
|
||||
self.assertNotContains(res, "<dd>%s</dd>" % sub['neutron_net_id'])
|
||||
self.assertNotContains(res,
|
||||
"<dd>%s</dd>" % sub['neutron_subnet_id'])
|
||||
network_get_calls = [mock.call(mock.ANY, sub['neutron_net_id']
|
||||
) for sub in share_network_subnets]
|
||||
subnet_get_calls = [mock.call(mock.ANY, sub['neutron_subnet_id']
|
||||
) for sub in share_network_subnets]
|
||||
|
||||
api.neutron.network_get.assert_has_calls(network_get_calls,
|
||||
any_order=True)
|
||||
api.neutron.subnet_get.assert_has_calls(subnet_get_calls,
|
||||
any_order=True)
|
||||
self.assertContains(res, "<a href=\"/project/security_services"
|
||||
"/%s\">%s</a>" % (sec_service.id,
|
||||
sec_service.name), 1, 200)
|
||||
@ -175,10 +213,6 @@ class ShareNetworksViewTests(test.TestCase):
|
||||
mock.ANY, search_opts={'share_network_id': share_net.id})
|
||||
api_manila.share_network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.id)
|
||||
api.neutron.network_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_net_id)
|
||||
api.neutron.subnet_get.assert_called_once_with(
|
||||
mock.ANY, share_net.neutron_subnet_id)
|
||||
|
||||
def test_update_share_network(self):
|
||||
share_net = test_data.inactive_share_network
|
||||
|
@ -279,12 +279,46 @@ inactive_share_network = share_networks.ShareNetwork(
|
||||
|
||||
active_share_network = share_networks.ShareNetwork(
|
||||
share_networks.ShareNetworkManager(FakeAPIClient),
|
||||
{'id': '7f3d1c33-8d00-4511-29df-a2def31f3b5d',
|
||||
'name': 'test_share_net',
|
||||
'description': 'test share network',
|
||||
'status': 'ACTIVE',
|
||||
'neutron_net_id': 'fake_neutron_net_id',
|
||||
'neutron_subnet_id': 'fake_neutron_subnet_id'})
|
||||
{
|
||||
"id": "1324e7d3-fba8-45e4-bb37-b59c12eb06dc",
|
||||
"name": "net_my1",
|
||||
"project_id": "16e1ab15c35a457e9c2b2aa189f544e1",
|
||||
"created_at": "2019-10-02T17:49:43.000000",
|
||||
"description": "This is test share network",
|
||||
"security_service_update_support": True,
|
||||
"status": "active",
|
||||
"share_network_subnets": [
|
||||
{
|
||||
"id": "e4db03dc-6041-4c6a-a8f9-80bb4141a1eb",
|
||||
"availability_zone": None,
|
||||
"created_at": "2019-10-02T17:49:43.000000",
|
||||
"updated_at": "2019-10-03T12:17:39.000000",
|
||||
"segmentation_id": None,
|
||||
"neutron_net_id": "62187648-6617-4509-a780-ffc973a7fe43",
|
||||
"neutron_subnet_id": "2276888a-27c1-47c2-82a0-ea33050128b5",
|
||||
"ip_version": 4,
|
||||
"cidr": "172.24.5.0/24",
|
||||
"network_type": "flat",
|
||||
"mtu": 1500,
|
||||
"gateway": "172.24.5.1",
|
||||
},
|
||||
{
|
||||
"id": "e4db03dc-6041-4c6a-a8f9-80bb4141a1en",
|
||||
"availability_zone": "manila-zone-0",
|
||||
"created_at": "2019-10-02T17:49:43.000000",
|
||||
"updated_at": "2019-10-03T12:17:39.000000",
|
||||
"segmentation_id": None,
|
||||
"neutron_net_id": "62187648-6617-4509-a780-ffc973a7f333",
|
||||
"neutron_subnet_id": "2276888a-27c1-47c2-82a0-ea3305012905",
|
||||
"ip_version": 4,
|
||||
"cidr": "172.24.5.0/24",
|
||||
"network_type": "flat",
|
||||
"mtu": 1500,
|
||||
"gateway": "172.24.5.1",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
sec_service = security_services.SecurityService(
|
||||
security_services.SecurityServiceManager(FakeAPIClient),
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Switched share network creation to a two-step
|
||||
workflow. We now allow configuring an availability
|
||||
zone with the initial network subnet associated with
|
||||
the share network. Share network detail panels have
|
||||
been updated accordingly as well
|
Loading…
x
Reference in New Issue
Block a user