Enable zuul unit tests for stx-gui
Enable flake8 and fix tox errors resulting from that. Story: 2003863 Task: 27930 Change-Id: Ia331856cbd6862d3c9341435450a391a7c2a2fef Signed-off-by: Kristine Bujold <kristine.bujold@windriver.com>
This commit is contained in:
parent
f1013be39f
commit
182d8ff492
|
@ -158,6 +158,7 @@ man_pages = [
|
||||||
# dir menu entry, description, category)
|
# dir menu entry, description, category)
|
||||||
texinfo_documents = [
|
texinfo_documents = [
|
||||||
(master_doc, 'stx-gui', 'stx-gui Documentation',
|
(master_doc, 'stx-gui', 'stx-gui Documentation',
|
||||||
author, 'stx-gui', 'StarlingX Horizon plugins for new StarlingX services.',
|
author, 'stx-gui',
|
||||||
|
'StarlingX Horizon plugins for new StarlingX services.',
|
||||||
'Miscellaneous'),
|
'Miscellaneous'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
SRC_DIR="starlingx-dashboard"
|
SRC_DIR="starlingx-dashboard"
|
||||||
TIS_PATCH_VER=16
|
TIS_PATCH_VER=17
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
# 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) 2017 Wind River Systems, Inc.
|
# Copyright (c) 2017-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from starlingx_dashboard.api import base
|
from starlingx_dashboard.api import base
|
||||||
from starlingx_dashboard.api import dc_manager
|
from starlingx_dashboard.api import dc_manager
|
||||||
|
from starlingx_dashboard.api import fm
|
||||||
from starlingx_dashboard.api import neutron
|
from starlingx_dashboard.api import neutron
|
||||||
from starlingx_dashboard.api import nova
|
from starlingx_dashboard.api import nova
|
||||||
from starlingx_dashboard.api import fm
|
from starlingx_dashboard.api import patch
|
||||||
from starlingx_dashboard.api import sysinv
|
from starlingx_dashboard.api import sysinv
|
||||||
from starlingx_dashboard.api import vim
|
from starlingx_dashboard.api import vim
|
||||||
from starlingx_dashboard.api import patch
|
|
||||||
|
|
||||||
# TODO (ediardo): cleanup the imports below
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"base",
|
"base",
|
||||||
"dc_manager",
|
"dc_manager",
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
import six
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from horizon import exceptions
|
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,13 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
||||||
from openstack_dashboard.api.neutron import *
|
from openstack_dashboard.api.neutron import neutronclient
|
||||||
|
from openstack_dashboard.api.neutron import PortForwardingRule
|
||||||
|
from openstack_dashboard.api.neutron import ProviderNetwork
|
||||||
|
from openstack_dashboard.api.neutron import ProviderNetworkRange
|
||||||
|
from openstack_dashboard.api.neutron import ProviderNetworkType
|
||||||
|
from openstack_dashboard.api.neutron import ProviderTenantNetwork
|
||||||
|
from openstack_dashboard.api.neutron import QoSPolicy
|
||||||
|
|
||||||
|
|
||||||
def provider_network_type_list(request, **params):
|
def provider_network_type_list(request, **params):
|
||||||
|
|
|
@ -8,7 +8,8 @@ from novaclient.v2 import wrs_pci
|
||||||
from novaclient.v2 import wrs_providernets
|
from novaclient.v2 import wrs_providernets
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
from openstack_dashboard.api.nova import *
|
from openstack_dashboard.api.nova import nova_exceptions
|
||||||
|
from openstack_dashboard.api.nova import novaclient
|
||||||
|
|
||||||
|
|
||||||
def server_group_list(request, all_projects=False):
|
def server_group_list(request, all_projects=False):
|
||||||
|
@ -34,8 +35,7 @@ def provider_network_get(request, providernet_id):
|
||||||
|
|
||||||
|
|
||||||
class DeviceUsage(base.APIResourceWrapper):
|
class DeviceUsage(base.APIResourceWrapper):
|
||||||
"""Wrapper for Inventory Device Usage
|
"""Wrapper for Inventory Device Usage"""
|
||||||
"""
|
|
||||||
_attrs = ['device_id', 'device_name', 'vendor_id', 'class_id',
|
_attrs = ['device_id', 'device_name', 'vendor_id', 'class_id',
|
||||||
'pci_vfs_configured', 'pci_vfs_used',
|
'pci_vfs_configured', 'pci_vfs_used',
|
||||||
'pci_pfs_configured', 'pci_pfs_used']
|
'pci_pfs_configured', 'pci_pfs_used']
|
||||||
|
@ -56,8 +56,7 @@ def get_device_usage(request, device_id):
|
||||||
|
|
||||||
|
|
||||||
class DetailUsage(base.APIResourceWrapper):
|
class DetailUsage(base.APIResourceWrapper):
|
||||||
"""Wrapper for Inventory Device Usage
|
"""Wrapper for Inventory Device Usage"""
|
||||||
"""
|
|
||||||
_attrs = ['host',
|
_attrs = ['host',
|
||||||
'pci_vfs_configured', 'pci_vfs_used',
|
'pci_vfs_configured', 'pci_vfs_used',
|
||||||
'pci_pfs_configured', 'pci_pfs_used']
|
'pci_pfs_configured', 'pci_pfs_used']
|
||||||
|
|
|
@ -14,10 +14,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
try:
|
|
||||||
from urlparse import urlparse
|
from six.moves.urllib.parse import urlparse
|
||||||
except ModuleNotFoundError:
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
from starlingx_dashboard.api import base as stx_base
|
|
||||||
|
|
||||||
import cgcs_patch.constants as patch_constants
|
import cgcs_patch.constants as patch_constants
|
||||||
import sysinv.common.constants as constants
|
import sysinv.common.constants as constants
|
||||||
|
@ -2005,12 +2004,14 @@ class InterfaceNetwork(base.APIResourceWrapper):
|
||||||
|
|
||||||
|
|
||||||
def interface_network_list_by_host(request, host_uuid):
|
def interface_network_list_by_host(request, host_uuid):
|
||||||
interface_networks = cgtsclient(request).interface_network.list_by_host(host_uuid)
|
interface_networks = cgtsclient(request).interface_network.list_by_host(
|
||||||
|
host_uuid)
|
||||||
return [InterfaceNetwork(n) for n in interface_networks]
|
return [InterfaceNetwork(n) for n in interface_networks]
|
||||||
|
|
||||||
|
|
||||||
def interface_network_list_by_interface(request, interface_uuid):
|
def interface_network_list_by_interface(request, interface_uuid):
|
||||||
interface_networks = cgtsclient(request).interface_network.list_by_interface(interface_uuid)
|
interface_networks = cgtsclient(request).interface_network.\
|
||||||
|
list_by_interface(interface_uuid)
|
||||||
return [InterfaceNetwork(n) for n in interface_networks]
|
return [InterfaceNetwork(n) for n in interface_networks]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,12 @@
|
||||||
# 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) 2016 Wind River Systems, Inc.
|
# Copyright (c) 2016-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
try:
|
|
||||||
from urlparse import urlparse
|
from six.moves.urllib.parse import urlparse
|
||||||
except ModuleNotFoundError:
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,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-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ from django.utils.translation import ungettext_lazy
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from horizon.utils import filters as utils_filters
|
from horizon.utils import filters as utils_filters
|
||||||
from openstack_dashboard import api
|
|
||||||
from starlingx_dashboard import api as stx_api
|
from starlingx_dashboard import api as stx_api
|
||||||
|
|
||||||
SUPPRESSION_STATUS_CHOICES = (
|
SUPPRESSION_STATUS_CHOICES = (
|
||||||
|
|
|
@ -16,7 +16,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-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ 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 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.fault_management import tables
|
from starlingx_dashboard.dashboards.admin.fault_management import tables
|
||||||
|
|
||||||
|
@ -115,9 +114,6 @@ class ActiveAlarmsTab(tabs.TableTab):
|
||||||
def get_alarms_data(self):
|
def get_alarms_data(self):
|
||||||
search_opts = {}
|
search_opts = {}
|
||||||
# get retrieve parameters from request/session env
|
# get retrieve parameters from request/session env
|
||||||
marker = \
|
|
||||||
self.request.GET.get(tables.AlarmsTable._meta.pagination_param,
|
|
||||||
None)
|
|
||||||
limit = \
|
limit = \
|
||||||
self.request.GET.get(tables.AlarmsTable._meta.limit_param,
|
self.request.GET.get(tables.AlarmsTable._meta.limit_param,
|
||||||
None)
|
None)
|
||||||
|
|
|
@ -16,7 +16,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-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ from horizon import exceptions
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
from horizon import views
|
from horizon import views
|
||||||
from openstack_dashboard.api.base import is_service_enabled
|
from openstack_dashboard.api.base import is_service_enabled
|
||||||
from starlingx_dashboard.api import fm
|
|
||||||
from starlingx_dashboard.api import dc_manager
|
from starlingx_dashboard.api import dc_manager
|
||||||
|
from starlingx_dashboard.api import fm
|
||||||
|
|
||||||
from starlingx_dashboard.dashboards.admin.fault_management import \
|
from starlingx_dashboard.dashboards.admin.fault_management import \
|
||||||
tabs as project_tabs
|
tabs as project_tabs
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 Wind River Systems, Inc.
|
# Copyright (c) 2016-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -34,4 +34,5 @@ class HostTopology(horizon.Panel):
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
dashboard.Admin.register(HostTopology)
|
dashboard.Admin.register(HostTopology)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 Wind River Systems, Inc.
|
# Copyright (c) 2016-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -12,8 +12,8 @@ from starlingx_dashboard.dashboards.admin.fault_management import \
|
||||||
tables as fm_tables
|
tables as fm_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 \
|
from starlingx_dashboard.dashboards.admin.providernets.providernets.ranges \
|
||||||
tables as sr_tables
|
import tables as sr_tables
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016 Wind River Systems, Inc.
|
# Copyright (c) 2016-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -159,14 +159,14 @@ class JSONView(View):
|
||||||
tenant_id = self.request.user.tenant_id
|
tenant_id = self.request.user.tenant_id
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
if (resource.get('tenant_id') and
|
if (resource.get('tenant_id') and
|
||||||
tenant_id != resource.get('tenant_id')):
|
tenant_id != resource.get('tenant_id')):
|
||||||
continue
|
continue
|
||||||
resource['url'] = reverse(view, None, [str(resource['id'])])
|
resource['url'] = reverse(view, None, [str(resource['id'])])
|
||||||
|
|
||||||
def _check_router_external_port(self, ports, router_id, network_id):
|
def _check_router_external_port(self, ports, router_id, network_id):
|
||||||
for port in ports:
|
for port in ports:
|
||||||
if (port['network_id'] == network_id and
|
if (port['network_id'] == network_id and
|
||||||
port['device_id'] == router_id):
|
port['device_id'] == router_id):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,8 @@ class CreateAddress(tables.LinkAction):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if interface.ifclass == 'platform':
|
if interface.ifclass == 'platform':
|
||||||
interface_networks = stx_api.sysinv.interface_network_list_by_interface(request,
|
interface_networks = stx_api.sysinv.\
|
||||||
interface.uuid)
|
interface_network_list_by_interface(request, interface.uuid)
|
||||||
for interface_network in interface_networks:
|
for interface_network in interface_networks:
|
||||||
if interface_network.network_type in ALLOWED_INTERFACE_TYPES:
|
if interface_network.network_type in ALLOWED_INTERFACE_TYPES:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -390,10 +390,6 @@ class AddInterface(forms.SelfHandlingForm):
|
||||||
|
|
||||||
host_uuid = kwargs['initial']['ihost_uuid']
|
host_uuid = kwargs['initial']['ihost_uuid']
|
||||||
|
|
||||||
# Retrieve SDN configuration
|
|
||||||
sdn_enabled = kwargs['initial']['sdn_enabled']
|
|
||||||
sdn_l3_mode = kwargs['initial']['sdn_l3_mode_enabled']
|
|
||||||
|
|
||||||
# Populate Address Pool selections
|
# Populate Address Pool selections
|
||||||
pools = sysinv.address_pool_list(self.request)
|
pools = sysinv.address_pool_list(self.request)
|
||||||
self.fields['ipv4_pool'].choices = _get_ipv4_pool_choices(pools)
|
self.fields['ipv4_pool'].choices = _get_ipv4_pool_choices(pools)
|
||||||
|
@ -640,23 +636,19 @@ class UpdateInterface(AddInterface):
|
||||||
ifclass_val = kwargs['initial']['ifclass']
|
ifclass_val = kwargs['initial']['ifclass']
|
||||||
host_uuid = kwargs['initial']['ihost_uuid']
|
host_uuid = kwargs['initial']['ihost_uuid']
|
||||||
|
|
||||||
# Get the SDN configuration
|
|
||||||
sdn_enabled = kwargs['initial']['sdn_enabled']
|
|
||||||
sdn_l3_mode = kwargs['initial']['sdn_l3_mode_enabled']
|
|
||||||
|
|
||||||
this_interface_id = kwargs['initial']['id']
|
this_interface_id = kwargs['initial']['id']
|
||||||
|
|
||||||
iftype_val = kwargs['initial']['iftype']
|
iftype_val = kwargs['initial']['iftype']
|
||||||
|
|
||||||
interface_networks = sysinv.interface_network_list_by_interface(self.request,
|
interface_networks = sysinv.interface_network_list_by_interface(
|
||||||
this_interface_id)
|
self.request, this_interface_id)
|
||||||
if ifclass_val == 'platform':
|
if ifclass_val == 'platform':
|
||||||
# Load the networks associated with this interface
|
# Load the networks associated with this interface
|
||||||
network_choices = self.fields['networks'].choices
|
network_choices = self.fields['networks'].choices
|
||||||
network_choice_dict = dict(network_choices)
|
network_choice_dict = dict(network_choices)
|
||||||
initial_networks = []
|
initial_networks = []
|
||||||
for i in interface_networks:
|
for i in interface_networks:
|
||||||
for uuid, name in network_choice_dict.items():
|
for uuid in network_choice_dict.keys():
|
||||||
if i.network_uuid == uuid:
|
if i.network_uuid == uuid:
|
||||||
initial_networks.append(uuid)
|
initial_networks.append(uuid)
|
||||||
|
|
||||||
|
@ -750,7 +742,8 @@ class UpdateInterface(AddInterface):
|
||||||
ifclass = cleaned_data.get('ifclass')
|
ifclass = cleaned_data.get('ifclass')
|
||||||
interface_id = cleaned_data.get('id')
|
interface_id = cleaned_data.get('id')
|
||||||
networks = cleaned_data.pop('networks', [])
|
networks = cleaned_data.pop('networks', [])
|
||||||
interface_networks = sysinv.interface_network_list_by_interface(self.request, interface_id)
|
interface_networks = sysinv.interface_network_list_by_interface(
|
||||||
|
self.request, interface_id)
|
||||||
network_ids = []
|
network_ids = []
|
||||||
networks_to_add = []
|
networks_to_add = []
|
||||||
networks_to_remove = []
|
networks_to_remove = []
|
||||||
|
@ -773,7 +766,8 @@ class UpdateInterface(AddInterface):
|
||||||
interface_networks_to_remove.append(i.uuid)
|
interface_networks_to_remove.append(i.uuid)
|
||||||
cleaned_data['networks'] = network_ids
|
cleaned_data['networks'] = network_ids
|
||||||
cleaned_data['networks_to_add'] = networks_to_add
|
cleaned_data['networks_to_add'] = networks_to_add
|
||||||
cleaned_data['interface_networks_to_remove'] = interface_networks_to_remove
|
cleaned_data['interface_networks_to_remove'] = \
|
||||||
|
interface_networks_to_remove
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
|
@ -855,7 +849,8 @@ class UpdateInterface(AddInterface):
|
||||||
else:
|
else:
|
||||||
del data['networks']
|
del data['networks']
|
||||||
if data['networks_to_add']:
|
if data['networks_to_add']:
|
||||||
data['networks_to_add'] = str(",".join(data['networks_to_add']))
|
data['networks_to_add'] = \
|
||||||
|
str(",".join(data['networks_to_add']))
|
||||||
else:
|
else:
|
||||||
del data['networks_to_add']
|
del data['networks_to_add']
|
||||||
if data['interface_networks_to_remove']:
|
if data['interface_networks_to_remove']:
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2016 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -55,7 +55,8 @@ def get_port_data(request, host_id, interface=None):
|
||||||
# neighbours
|
# neighbours
|
||||||
neighbour_list = \
|
neighbour_list = \
|
||||||
stx_api.sysinv.host_lldpneighbour_list(request, host_id)
|
stx_api.sysinv.host_lldpneighbour_list(request, host_id)
|
||||||
interface_list = stx_api.sysinv.host_interface_list(request, host_id)
|
interface_list = stx_api.sysinv.host_interface_list(request,
|
||||||
|
host_id)
|
||||||
|
|
||||||
for p in port_list:
|
for p in port_list:
|
||||||
port_info = "%s (%s, %s, " % (p.get_port_display_name(),
|
port_info = "%s (%s, %s, " % (p.get_port_display_name(),
|
||||||
|
@ -184,13 +185,14 @@ class AddInterfaceProfileView(forms.ModalFormView):
|
||||||
try:
|
try:
|
||||||
host = stx_api.sysinv.host_get(self.request, host_id)
|
host = stx_api.sysinv.host_get(self.request, host_id)
|
||||||
|
|
||||||
all_ports = stx_api.sysinv.host_port_list(self.request, host.uuid)
|
all_ports = stx_api.sysinv.host_port_list(self.request,
|
||||||
|
host.uuid)
|
||||||
host.ports = [p for p in all_ports if p.interface_uuid]
|
host.ports = [p for p in all_ports if p.interface_uuid]
|
||||||
for p in host.ports:
|
for p in host.ports:
|
||||||
p.namedisplay = p.get_port_display_name()
|
p.namedisplay = p.get_port_display_name()
|
||||||
|
|
||||||
host.interfaces = stx_api.sysinv.host_interface_list(self.request,
|
host.interfaces = stx_api.sysinv.host_interface_list(
|
||||||
host.uuid)
|
self.request, host.uuid)
|
||||||
for i in host.interfaces:
|
for i in host.interfaces:
|
||||||
i.ports = [p.get_port_display_name()
|
i.ports = [p.get_port_display_name()
|
||||||
for p in all_ports if
|
for p in all_ports if
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2014 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -339,7 +339,8 @@ class AddMemoryProfile(forms.SelfHandlingForm):
|
||||||
|
|
||||||
memoryProfileName = data['profilename']
|
memoryProfileName = data['profilename']
|
||||||
try:
|
try:
|
||||||
memoryProfile = stx_api.sysinv.host_memprofile_create(request, **data)
|
memoryProfile = stx_api.sysinv.host_memprofile_create(
|
||||||
|
request, **data)
|
||||||
msg = _('Memory Profile "%s" was successfully created.') % \
|
msg = _('Memory Profile "%s" was successfully created.') % \
|
||||||
memoryProfileName
|
memoryProfileName
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2014 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -85,13 +85,15 @@ class AddMemoryProfileView(forms.ModalFormView):
|
||||||
host_id = self.kwargs['host_id']
|
host_id = self.kwargs['host_id']
|
||||||
try:
|
try:
|
||||||
host = stx_api.sysinv.host_get(self.request, host_id)
|
host = stx_api.sysinv.host_get(self.request, host_id)
|
||||||
host.nodes = stx_api.sysinv.host_node_list(self.request, host.uuid)
|
host.nodes = stx_api.sysinv.host_node_list(self.request,
|
||||||
|
host.uuid)
|
||||||
host.memory = \
|
host.memory = \
|
||||||
stx_api.sysinv.host_memory_list(self.request, host.uuid)
|
stx_api.sysinv.host_memory_list(self.request, host.uuid)
|
||||||
|
|
||||||
numa_node_tuple_list = []
|
numa_node_tuple_list = []
|
||||||
for m in host.memory:
|
for m in host.memory:
|
||||||
node = stx_api.sysinv.host_node_get(self.request, m.inode_uuid)
|
node = stx_api.sysinv.host_node_get(self.request,
|
||||||
|
m.inode_uuid)
|
||||||
numa_node_tuple_list.append((node.numa_node, m))
|
numa_node_tuple_list.append((node.numa_node, m))
|
||||||
|
|
||||||
host.numa_nodes = numa_node_tuple_list
|
host.numa_nodes = numa_node_tuple_list
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2014 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -39,7 +39,8 @@ class UpdateView(forms.ModalFormView):
|
||||||
port_id = self.kwargs['port_id']
|
port_id = self.kwargs['port_id']
|
||||||
host_id = self.kwargs['host_id']
|
host_id = self.kwargs['host_id']
|
||||||
try:
|
try:
|
||||||
self._object = stx_api.sysinv.host_port_get(self.request, port_id)
|
self._object = stx_api.sysinv.host_port_get(self.request,
|
||||||
|
port_id)
|
||||||
self._object.host_id = host_id
|
self._object.host_id = host_id
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse("horizon:project:networks:detail",
|
redirect = reverse("horizon:project:networks:detail",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -75,7 +75,8 @@ class AddSensorGroup(forms.SelfHandlingForm):
|
||||||
del data['hostname']
|
del data['hostname']
|
||||||
|
|
||||||
# The REST API takes care of creating the sensorgroup and assoc
|
# The REST API takes care of creating the sensorgroup and assoc
|
||||||
sensorgroup = stx_api.sysinv.host_sensorgroup_create(request, **data)
|
sensorgroup = stx_api.sysinv.host_sensorgroup_create(request,
|
||||||
|
**data)
|
||||||
|
|
||||||
msg = _('Sensor group was successfully created.')
|
msg = _('Sensor group was successfully created.')
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
|
@ -208,9 +209,10 @@ class UpdateSensorGroup(forms.SelfHandlingForm):
|
||||||
mysensorgroupname = data.pop('sensorgroupname', None)
|
mysensorgroupname = data.pop('sensorgroupname', None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sensorgroup = stx_api.sysinv.host_sensorgroup_update(request,
|
sensorgroup = \
|
||||||
sensorgroup_id,
|
stx_api.sysinv.host_sensorgroup_update(request,
|
||||||
**data)
|
sensorgroup_id,
|
||||||
|
**data)
|
||||||
|
|
||||||
msg = _('SensorGroup "%s" was '
|
msg = _('SensorGroup "%s" was '
|
||||||
'successfully updated.') % mysensorgroupname
|
'successfully updated.') % mysensorgroupname
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -209,7 +209,8 @@ class RelearnSensorModel(tables.Action):
|
||||||
def single(self, table, request, obj_ids):
|
def single(self, table, request, obj_ids):
|
||||||
LOG.debug("requesting relearn of sensor model for host "
|
LOG.debug("requesting relearn of sensor model for host "
|
||||||
"%s", table.kwargs['host'].uuid)
|
"%s", table.kwargs['host'].uuid)
|
||||||
stx_api.sysinv.host_sensorgroup_relearn(request, table.kwargs['host'].uuid)
|
stx_api.sysinv.host_sensorgroup_relearn(request,
|
||||||
|
table.kwargs['host'].uuid)
|
||||||
|
|
||||||
|
|
||||||
class SensorGroupsTable(tables.DataTable):
|
class SensorGroupsTable(tables.DataTable):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -74,8 +74,9 @@ class UpdateSensorGroupView(forms.ModalFormView):
|
||||||
LOG.debug("sensorgroup_id=%s kwargs=%s",
|
LOG.debug("sensorgroup_id=%s kwargs=%s",
|
||||||
sensorgroup_id, self.kwargs)
|
sensorgroup_id, self.kwargs)
|
||||||
try:
|
try:
|
||||||
self._object = stx_api.sysinv.host_sensorgroup_get(self.request,
|
self._object = \
|
||||||
sensorgroup_id)
|
stx_api.sysinv.host_sensorgroup_get(self.request,
|
||||||
|
sensorgroup_id)
|
||||||
self._object.host_id = host_id
|
self._object.host_id = host_id
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -147,7 +148,8 @@ class DetailSensorView(views.HorizonTemplateView):
|
||||||
if not hasattr(self, "_sensor"):
|
if not hasattr(self, "_sensor"):
|
||||||
sensor_id = self.kwargs['sensor_id']
|
sensor_id = self.kwargs['sensor_id']
|
||||||
try:
|
try:
|
||||||
sensor = stx_api.sysinv.host_sensor_get(self.request, sensor_id)
|
sensor = stx_api.sysinv.host_sensor_get(self.request,
|
||||||
|
sensor_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:admin:inventory:index')
|
redirect = reverse('horizon:admin:inventory:index')
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
|
@ -194,8 +196,9 @@ class DetailSensorGroupView(views.HorizonTemplateView):
|
||||||
if not hasattr(self, "_sensorgroup"):
|
if not hasattr(self, "_sensorgroup"):
|
||||||
sensorgroup_id = self.kwargs['sensorgroup_id']
|
sensorgroup_id = self.kwargs['sensorgroup_id']
|
||||||
try:
|
try:
|
||||||
sensorgroup = stx_api.sysinv.host_sensorgroup_get(self.request,
|
sensorgroup = \
|
||||||
sensorgroup_id)
|
stx_api.sysinv.host_sensorgroup_get(self.request,
|
||||||
|
sensorgroup_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:admin:inventory:index')
|
redirect = reverse('horizon:admin:inventory:index')
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
|
|
|
@ -40,7 +40,8 @@ class AddDiskProfile(forms.SelfHandlingForm):
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
diskProfileName = data['profilename']
|
diskProfileName = data['profilename']
|
||||||
try:
|
try:
|
||||||
diskProfile = stx_api.sysinv.host_diskprofile_create(request, **data)
|
diskProfile = stx_api.sysinv.host_diskprofile_create(request,
|
||||||
|
**data)
|
||||||
|
|
||||||
msg = _('Storage Profile "%s" was successfully created.') \
|
msg = _('Storage Profile "%s" was successfully created.') \
|
||||||
% diskProfileName
|
% diskProfileName
|
||||||
|
@ -72,13 +73,12 @@ class EditStorageVolume(forms.SelfHandlingForm):
|
||||||
help_text=_("Assign disk to journal "
|
help_text=_("Assign disk to journal "
|
||||||
"storage volume."))
|
"storage volume."))
|
||||||
|
|
||||||
journal_size_gib = forms.CharField(label=_("Journal Size GiB"),
|
journal_size_gib = forms.CharField(
|
||||||
required=False,
|
label=_("Journal Size GiB"),
|
||||||
initial=stx_api.sysinv.JOURNAL_DEFAULT_SIZE,
|
required=False,
|
||||||
widget=forms.TextInput(attrs={
|
initial=stx_api.sysinv.JOURNAL_DEFAULT_SIZE,
|
||||||
'data-slug': 'journal_size_gib'}),
|
widget=forms.TextInput(attrs={'data-slug': 'journal_size_gib'}),
|
||||||
help_text=_("Journal's size for the "
|
help_text=_("Journal's size for the current OSD."))
|
||||||
"current OSD."))
|
|
||||||
|
|
||||||
failure_url = 'horizon:admin:inventory:detail'
|
failure_url = 'horizon:admin:inventory:detail'
|
||||||
|
|
||||||
|
@ -127,7 +127,8 @@ class EditStorageVolume(forms.SelfHandlingForm):
|
||||||
data['journal_location'] = journal
|
data['journal_location'] = journal
|
||||||
else:
|
else:
|
||||||
data['journal_location'] = None
|
data['journal_location'] = None
|
||||||
data['journal_size_mib'] = stx_api.sysinv.JOURNAL_DEFAULT_SIZE * 1024
|
data['journal_size_mib'] = \
|
||||||
|
stx_api.sysinv.JOURNAL_DEFAULT_SIZE * 1024
|
||||||
|
|
||||||
del data['journal_locations']
|
del data['journal_locations']
|
||||||
del data['id']
|
del data['id']
|
||||||
|
@ -216,16 +217,15 @@ class AddStorageVolume(forms.SelfHandlingForm):
|
||||||
"journal storage "
|
"journal storage "
|
||||||
"volume."))
|
"volume."))
|
||||||
|
|
||||||
journal_size_gib = forms.CharField(label=_("Journal Size GiB"),
|
journal_size_gib = forms.CharField(
|
||||||
required=False,
|
label=_("Journal Size GiB"),
|
||||||
initial=stx_api.sysinv.JOURNAL_DEFAULT_SIZE,
|
required=False,
|
||||||
widget=forms.TextInput(attrs={
|
initial=stx_api.sysinv.JOURNAL_DEFAULT_SIZE,
|
||||||
'class': 'switched',
|
widget=forms.TextInput(attrs={
|
||||||
'data-switch-on': 'function',
|
'class': 'switched',
|
||||||
'data-function-osd':
|
'data-switch-on': 'function',
|
||||||
_("Journal Size GiB")}),
|
'data-function-osd': _("Journal Size GiB")}),
|
||||||
help_text=_("Journal's size for the"
|
help_text=_("Journal's size for the current OSD."))
|
||||||
"current OSD."))
|
|
||||||
|
|
||||||
tiers = forms.ChoiceField(label=_("Storage Tier"),
|
tiers = forms.ChoiceField(label=_("Storage Tier"),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -245,7 +245,8 @@ class AddStorageVolume(forms.SelfHandlingForm):
|
||||||
this_stor_uuid = 0
|
this_stor_uuid = 0
|
||||||
host_uuid = kwargs['initial']['ihost_uuid']
|
host_uuid = kwargs['initial']['ihost_uuid']
|
||||||
|
|
||||||
avail_disk_list = stx_api.sysinv.host_disk_list(self.request, host_uuid)
|
avail_disk_list = stx_api.sysinv.host_disk_list(self.request,
|
||||||
|
host_uuid)
|
||||||
disk_tuple_list = []
|
disk_tuple_list = []
|
||||||
for d in avail_disk_list:
|
for d in avail_disk_list:
|
||||||
if d.istor_uuid and d.istor_uuid != this_stor_uuid:
|
if d.istor_uuid and d.istor_uuid != this_stor_uuid:
|
||||||
|
@ -321,7 +322,8 @@ class AddStorageVolume(forms.SelfHandlingForm):
|
||||||
data['journal_location'] = journal
|
data['journal_location'] = journal
|
||||||
else:
|
else:
|
||||||
data['journal_location'] = None
|
data['journal_location'] = None
|
||||||
data['journal_size_mib'] = stx_api.sysinv.JOURNAL_DEFAULT_SIZE * 1024
|
data['journal_size_mib'] = \
|
||||||
|
stx_api.sysinv.JOURNAL_DEFAULT_SIZE * 1024
|
||||||
|
|
||||||
try:
|
try:
|
||||||
del data['host_id']
|
del data['host_id']
|
||||||
|
@ -543,7 +545,8 @@ class AddPhysicalVolume(forms.SelfHandlingForm):
|
||||||
if stx_api.sysinv.SUBFUNCTIONS_COMPUTE in subfunctions:
|
if stx_api.sysinv.SUBFUNCTIONS_COMPUTE in subfunctions:
|
||||||
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL]
|
compatible_lvgs += [stx_api.sysinv.LVG_NOVA_LOCAL]
|
||||||
|
|
||||||
avail_disk_list = stx_api.sysinv.host_disk_list(self.request, host_uuid)
|
avail_disk_list = stx_api.sysinv.host_disk_list(self.request,
|
||||||
|
host_uuid)
|
||||||
ilvg_list = stx_api.sysinv.host_lvg_list(self.request, host_uuid)
|
ilvg_list = stx_api.sysinv.host_lvg_list(self.request, host_uuid)
|
||||||
partitions = stx_api.sysinv.host_disk_partition_list(self.request,
|
partitions = stx_api.sysinv.host_disk_partition_list(self.request,
|
||||||
host_uuid)
|
host_uuid)
|
||||||
|
@ -558,7 +561,8 @@ class AddPhysicalVolume(forms.SelfHandlingForm):
|
||||||
|
|
||||||
for lvg in ilvg_list:
|
for lvg in ilvg_list:
|
||||||
if (lvg.lvm_vg_name in compatible_lvgs and
|
if (lvg.lvm_vg_name in compatible_lvgs and
|
||||||
lvg.vg_state in [stx_api.sysinv.LVG_ADD, stx_api.sysinv.LVG_PROV]):
|
lvg.vg_state in [stx_api.sysinv.LVG_ADD,
|
||||||
|
stx_api.sysinv.LVG_PROV]):
|
||||||
if (lvg.lvm_vg_name == stx_api.sysinv.LVG_CINDER_VOLUMES and
|
if (lvg.lvm_vg_name == stx_api.sysinv.LVG_CINDER_VOLUMES and
|
||||||
pv_cinder_volumes):
|
pv_cinder_volumes):
|
||||||
continue
|
continue
|
||||||
|
@ -777,7 +781,8 @@ class CreatePartition(forms.SelfHandlingForm):
|
||||||
|
|
||||||
# Populate disk choices.
|
# Populate disk choices.
|
||||||
host_uuid = kwargs['initial']['ihost_uuid']
|
host_uuid = kwargs['initial']['ihost_uuid']
|
||||||
avail_disk_list = stx_api.sysinv.host_disk_list(self.request, host_uuid)
|
avail_disk_list = stx_api.sysinv.host_disk_list(self.request,
|
||||||
|
host_uuid)
|
||||||
disk_tuple_list = []
|
disk_tuple_list = []
|
||||||
for d in avail_disk_list:
|
for d in avail_disk_list:
|
||||||
disk_model = d.get_model_num()
|
disk_model = d.get_model_num()
|
||||||
|
@ -812,7 +817,8 @@ class CreatePartition(forms.SelfHandlingForm):
|
||||||
del data['size_gib']
|
del data['size_gib']
|
||||||
data['type_guid'] = stx_api.sysinv.USER_PARTITION_PHYS_VOL
|
data['type_guid'] = stx_api.sysinv.USER_PARTITION_PHYS_VOL
|
||||||
# The REST API takes care of creating the partition.
|
# The REST API takes care of creating the partition.
|
||||||
partition = stx_api.sysinv.host_disk_partition_create(request, **data)
|
partition = stx_api.sysinv.host_disk_partition_create(request,
|
||||||
|
**data)
|
||||||
|
|
||||||
msg = _('Partition was successfully created.')
|
msg = _('Partition was successfully created.')
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# Copyright (c) 2015-2018 Wind River Systems, Inc.
|
||||||
|
|
||||||
# Copyright (c) 2015-2017 Wind River Systems, Inc.
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# Copyright (c) 2015-2018 Wind River Systems, Inc.
|
||||||
|
|
||||||
# Copyright (c) 2015 Wind River Systems, Inc.
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# Copyright (c) 2015-2018 Wind River Systems, Inc.
|
||||||
|
|
||||||
# Copyright (c) 2015 Wind River Systems, Inc.
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# Copyright (c) 2015-2018 Wind River Systems, Inc.
|
||||||
|
|
||||||
# Copyright (c) 2015 Wind River Systems, Inc.
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# Copyright (c) 2015-2018 Wind River Systems, Inc.
|
||||||
|
|
||||||
# Copyright (c) 2015 Wind River Systems, Inc.
|
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -720,13 +720,16 @@ class Hosts(tables.DataTable):
|
||||||
display_choices=stx_api.sysinv.Host.PERSONALITY_DISPLAY_CHOICES)
|
display_choices=stx_api.sysinv.Host.PERSONALITY_DISPLAY_CHOICES)
|
||||||
admin = tables.Column("administrative",
|
admin = tables.Column("administrative",
|
||||||
verbose_name=_("Admin State"),
|
verbose_name=_("Admin State"),
|
||||||
display_choices=stx_api.sysinv.Host.ADMIN_DISPLAY_CHOICES)
|
display_choices=stx_api.sysinv.
|
||||||
|
Host.ADMIN_DISPLAY_CHOICES)
|
||||||
oper = tables.Column("operational",
|
oper = tables.Column("operational",
|
||||||
verbose_name=_("Operational State"),
|
verbose_name=_("Operational State"),
|
||||||
display_choices=stx_api.sysinv.Host.OPER_DISPLAY_CHOICES)
|
display_choices=stx_api.sysinv.
|
||||||
|
Host.OPER_DISPLAY_CHOICES)
|
||||||
avail = tables.Column("availability",
|
avail = tables.Column("availability",
|
||||||
verbose_name=_("Availability State"),
|
verbose_name=_("Availability State"),
|
||||||
display_choices=stx_api.sysinv.Host.AVAIL_DISPLAY_CHOICES)
|
display_choices=stx_api.sysinv.
|
||||||
|
Host.AVAIL_DISPLAY_CHOICES)
|
||||||
uptime = tables.Column('boottime',
|
uptime = tables.Column('boottime',
|
||||||
verbose_name=_('Uptime'),
|
verbose_name=_('Uptime'),
|
||||||
filters=(timesince,),
|
filters=(timesince,),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -101,7 +101,8 @@ class HostsTab(tabs.TableTab):
|
||||||
return hosts
|
return hosts
|
||||||
|
|
||||||
def get_hostscontroller_data(self):
|
def get_hostscontroller_data(self):
|
||||||
controllers = self.get_hosts_data(stx_api.sysinv.PERSONALITY_CONTROLLER)
|
controllers = self.get_hosts_data(
|
||||||
|
stx_api.sysinv.PERSONALITY_CONTROLLER)
|
||||||
|
|
||||||
return controllers
|
return controllers
|
||||||
|
|
||||||
|
@ -543,10 +544,12 @@ class InterfacesTab(tabs.TableTab):
|
||||||
|
|
||||||
platform_network_names = []
|
platform_network_names = []
|
||||||
if i.ifclass == 'platform':
|
if i.ifclass == 'platform':
|
||||||
for interface_network in stx_api.sysinv.interface_network_list_by_interface(self.request,
|
for interface_network in stx_api.sysinv.\
|
||||||
i.uuid):
|
interface_network_list_by_interface(
|
||||||
|
self.request, i.uuid):
|
||||||
if str(interface_network.network_id) in i.networks:
|
if str(interface_network.network_id) in i.networks:
|
||||||
platform_network_names.append(interface_network.network_name)
|
platform_network_names.append(
|
||||||
|
interface_network.network_name)
|
||||||
i.platform_network_names = platform_network_names
|
i.platform_network_names = platform_network_names
|
||||||
|
|
||||||
if i.iftype == 'ethernet':
|
if i.iftype == 'ethernet':
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -27,6 +27,8 @@ from starlingx_dashboard.dashboards.admin.inventory.ports import \
|
||||||
views as port_views
|
views as port_views
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.sensors import \
|
from starlingx_dashboard.dashboards.admin.inventory.sensors import \
|
||||||
views as sensor_views
|
views as sensor_views
|
||||||
|
from starlingx_dashboard.dashboards.admin.inventory.storages import \
|
||||||
|
urls as storages_urls
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.storages import \
|
from starlingx_dashboard.dashboards.admin.inventory.storages import \
|
||||||
views as storage_views
|
views as storage_views
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.views import \
|
from starlingx_dashboard.dashboards.admin.inventory.views import \
|
||||||
|
@ -37,8 +39,6 @@ from starlingx_dashboard.dashboards.admin.inventory.views import \
|
||||||
IndexView
|
IndexView
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.views import \
|
from starlingx_dashboard.dashboards.admin.inventory.views import \
|
||||||
UpdateView
|
UpdateView
|
||||||
from starlingx_dashboard.dashboards.admin.inventory.storages \
|
|
||||||
import urls as storages_urls
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -64,7 +64,8 @@ class UpdateView(workflows.WorkflowView):
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
try:
|
try:
|
||||||
host = stx_api.sysinv.host_get(self.request, self.kwargs['host_id'])
|
host = stx_api.sysinv.host_get(self.request,
|
||||||
|
self.kwargs['host_id'])
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_("Unable to retrieve host data."))
|
_("Unable to retrieve host data."))
|
||||||
|
@ -109,8 +110,10 @@ class DetailView(tabs.TabbedTableView):
|
||||||
try:
|
try:
|
||||||
host = stx_api.sysinv.host_get(self.request, host_id)
|
host = stx_api.sysinv.host_get(self.request, host_id)
|
||||||
|
|
||||||
host.nodes = stx_api.sysinv.host_node_list(self.request, host.uuid)
|
host.nodes = stx_api.sysinv.host_node_list(self.request,
|
||||||
host.cpus = stx_api.sysinv.host_cpu_list(self.request, host.uuid)
|
host.uuid)
|
||||||
|
host.cpus = stx_api.sysinv.host_cpu_list(self.request,
|
||||||
|
host.uuid)
|
||||||
icpu_utils.restructure_host_cpu_data(host)
|
icpu_utils.restructure_host_cpu_data(host)
|
||||||
|
|
||||||
host.memorys = stx_api.sysinv.host_memory_list(self.request,
|
host.memorys = stx_api.sysinv.host_memory_list(self.request,
|
||||||
|
@ -121,13 +124,16 @@ class DetailView(tabs.TabbedTableView):
|
||||||
m.numa_node = n.numa_node
|
m.numa_node = n.numa_node
|
||||||
break
|
break
|
||||||
|
|
||||||
host.ports = stx_api.sysinv.host_port_list(self.request, host.uuid)
|
host.ports = stx_api.sysinv.host_port_list(self.request,
|
||||||
host.interfaces = stx_api.sysinv.host_interface_list(self.request,
|
host.uuid)
|
||||||
host.uuid)
|
host.interfaces = stx_api.sysinv.host_interface_list(
|
||||||
|
self.request, host.uuid)
|
||||||
host.devices = stx_api.sysinv.host_device_list(self.request,
|
host.devices = stx_api.sysinv.host_device_list(self.request,
|
||||||
host.uuid)
|
host.uuid)
|
||||||
host.disks = stx_api.sysinv.host_disk_list(self.request, host.uuid)
|
host.disks = stx_api.sysinv.host_disk_list(self.request,
|
||||||
host.stors = stx_api.sysinv.host_stor_list(self.request, host.uuid)
|
host.uuid)
|
||||||
|
host.stors = stx_api.sysinv.host_stor_list(self.request,
|
||||||
|
host.uuid)
|
||||||
host.pvs = stx_api.sysinv.host_pv_list(self.request, host.uuid)
|
host.pvs = stx_api.sysinv.host_pv_list(self.request, host.uuid)
|
||||||
host.partitions = stx_api.sysinv.host_disk_partition_list(
|
host.partitions = stx_api.sysinv.host_disk_partition_list(
|
||||||
self.request, host.uuid)
|
self.request, host.uuid)
|
||||||
|
@ -137,7 +143,8 @@ class DetailView(tabs.TabbedTableView):
|
||||||
p.status = stx_api.sysinv.PARTITION_STATUS_MSG[p.status]
|
p.status = stx_api.sysinv.PARTITION_STATUS_MSG[p.status]
|
||||||
|
|
||||||
host.lldpneighbours = \
|
host.lldpneighbours = \
|
||||||
stx_api.sysinv.host_lldpneighbour_list(self.request, host.uuid)
|
stx_api.sysinv.host_lldpneighbour_list(self.request,
|
||||||
|
host.uuid)
|
||||||
|
|
||||||
# Set the value for neighbours field for each port in the host.
|
# Set the value for neighbours field for each port in the host.
|
||||||
# This will be referenced in Interfaces table
|
# This will be referenced in Interfaces table
|
||||||
|
@ -151,7 +158,8 @@ class DetailView(tabs.TabbedTableView):
|
||||||
pv.pv_state = self._adjust_state_data(pv.pv_state,
|
pv.pv_state = self._adjust_state_data(pv.pv_state,
|
||||||
pv.lvm_vg_name)
|
pv.lvm_vg_name)
|
||||||
|
|
||||||
host.lvgs = stx_api.sysinv.host_lvg_list(self.request, host.uuid,
|
host.lvgs = stx_api.sysinv.host_lvg_list(self.request,
|
||||||
|
host.uuid,
|
||||||
get_params=True)
|
get_params=True)
|
||||||
|
|
||||||
# Adjust lvg state to be more "user friendly"
|
# Adjust lvg state to be more "user friendly"
|
||||||
|
|
|
@ -56,8 +56,8 @@ BM_TYPES_CHOICES = (
|
||||||
|
|
||||||
def ifprofile_applicable(request, host, profile):
|
def ifprofile_applicable(request, host, profile):
|
||||||
for interface in profile.interfaces:
|
for interface in profile.interfaces:
|
||||||
interface_networks = stx_api.sysinv.interface_network_list_by_interface(request,
|
interface_networks = stx_api.sysinv.\
|
||||||
interface.uuid)
|
interface_network_list_by_interface(request, interface.uuid)
|
||||||
if (stx_api.sysinv.PERSONALITY_COMPUTE == host._personality and
|
if (stx_api.sysinv.PERSONALITY_COMPUTE == host._personality and
|
||||||
any(interface_network.network_type == 'oam'
|
any(interface_network.network_type == 'oam'
|
||||||
for interface_network in interface_networks)):
|
for interface_network in interface_networks)):
|
||||||
|
@ -248,8 +248,8 @@ class UpdateHostInfoAction(workflows.Action):
|
||||||
attrs={'class': 'switched',
|
attrs={'class': 'switched',
|
||||||
'data-switch-on': 'personality',
|
'data-switch-on': 'personality',
|
||||||
'data-personality-' +
|
'data-personality-' +
|
||||||
stx_api.sysinv.PERSONALITY_COMPUTE: _(
|
stx_api.sysinv.PERSONALITY_COMPUTE:
|
||||||
"Host Name")}))
|
_("Host Name")}))
|
||||||
|
|
||||||
location = forms.CharField(label=_("Location"),
|
location = forms.CharField(label=_("Location"),
|
||||||
initial='location',
|
initial='location',
|
||||||
|
@ -345,8 +345,8 @@ class UpdateHostInfoAction(workflows.Action):
|
||||||
if host.nodes and host.cpus and host.ports:
|
if host.nodes and host.cpus and host.ports:
|
||||||
# Populate Available Cpu Profile Choices
|
# Populate Available Cpu Profile Choices
|
||||||
try:
|
try:
|
||||||
avail_cpu_profile_list = stx_api.sysinv.host_cpuprofile_list(
|
avail_cpu_profile_list = \
|
||||||
self.request)
|
stx_api.sysinv.host_cpuprofile_list(self.request)
|
||||||
|
|
||||||
host_profile = icpu_utils.HostCpuProfile(
|
host_profile = icpu_utils.HostCpuProfile(
|
||||||
host.subfunctions,
|
host.subfunctions,
|
||||||
|
@ -393,8 +393,8 @@ class UpdateHostInfoAction(workflows.Action):
|
||||||
self.fields[
|
self.fields[
|
||||||
'interfaceProfile'].widget = forms.widgets.HiddenInput()
|
'interfaceProfile'].widget = forms.widgets.HiddenInput()
|
||||||
|
|
||||||
if ((personality == 'storage' or 'compute' in host._subfunctions) and
|
if ((personality == 'storage' or
|
||||||
host.disks):
|
'compute' in host._subfunctions) and host.disks):
|
||||||
# Populate Available Disk Profile Choices
|
# Populate Available Disk Profile Choices
|
||||||
try:
|
try:
|
||||||
disk_profile_tuple_list = [
|
disk_profile_tuple_list = [
|
||||||
|
@ -467,10 +467,11 @@ class UpdateHostInfoAction(workflows.Action):
|
||||||
if cleaned_data['personality'] == stx_api.sysinv.PERSONALITY_STORAGE:
|
if cleaned_data['personality'] == stx_api.sysinv.PERSONALITY_STORAGE:
|
||||||
self._subfunctions = stx_api.sysinv.PERSONALITY_STORAGE
|
self._subfunctions = stx_api.sysinv.PERSONALITY_STORAGE
|
||||||
cleaned_data['subfunctions'] = self._subfunctions
|
cleaned_data['subfunctions'] = self._subfunctions
|
||||||
elif cleaned_data['personality'] == stx_api.sysinv.PERSONALITY_CONTROLLER:
|
elif cleaned_data['personality'] == \
|
||||||
|
stx_api.sysinv.PERSONALITY_CONTROLLER:
|
||||||
if self.system_type == constants.TS_AIO:
|
if self.system_type == constants.TS_AIO:
|
||||||
self._subfunctions = (stx_api.sysinv.PERSONALITY_CONTROLLER + ',' +
|
self._subfunctions = (stx_api.sysinv.PERSONALITY_CONTROLLER +
|
||||||
stx_api.sysinv.PERSONALITY_COMPUTE)
|
',' + stx_api.sysinv.PERSONALITY_COMPUTE)
|
||||||
else:
|
else:
|
||||||
self._subfunctions = stx_api.sysinv.PERSONALITY_CONTROLLER
|
self._subfunctions = stx_api.sysinv.PERSONALITY_CONTROLLER
|
||||||
cleaned_data['subfunctions'] = self._subfunctions
|
cleaned_data['subfunctions'] = self._subfunctions
|
||||||
|
@ -629,7 +630,8 @@ class BoardManagementAction(workflows.Action):
|
||||||
'class': 'switched',
|
'class': 'switched',
|
||||||
'data-switch-on': 'bm_type',
|
'data-switch-on': 'bm_type',
|
||||||
'data-bm_type-' +
|
'data-bm_type-' +
|
||||||
stx_api.sysinv.BM_TYPE_GENERIC: FIELD_LABEL_BM_CONFIRM_PASSWORD}),
|
stx_api.sysinv.BM_TYPE_GENERIC:
|
||||||
|
FIELD_LABEL_BM_CONFIRM_PASSWORD}),
|
||||||
required=False)
|
required=False)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
@ -639,8 +641,6 @@ class BoardManagementAction(workflows.Action):
|
||||||
if 'bm_ip' not in cleaned_data or not cleaned_data['bm_ip']:
|
if 'bm_ip' not in cleaned_data or not cleaned_data['bm_ip']:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_('Board management IP address is required.'))
|
_('Board management IP address is required.'))
|
||||||
raise forms.ValidationError(
|
|
||||||
_('Board management MAC address is required.'))
|
|
||||||
|
|
||||||
if 'bm_username' not in cleaned_data or not \
|
if 'bm_username' not in cleaned_data or not \
|
||||||
cleaned_data['bm_username']:
|
cleaned_data['bm_username']:
|
||||||
|
|
|
@ -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-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +89,8 @@ class CreateProviderNetwork(forms.SelfHandlingForm):
|
||||||
'mtu': data['mtu'],
|
'mtu': data['mtu'],
|
||||||
'vlan_transparent': data['vlan_transparent']}
|
'vlan_transparent': data['vlan_transparent']}
|
||||||
|
|
||||||
network = stx_api.neutron.provider_network_create(request, **params)
|
network = stx_api.neutron.provider_network_create(request,
|
||||||
|
**params)
|
||||||
msg = (_('Provider network %s was successfully created.') %
|
msg = (_('Provider network %s was successfully created.') %
|
||||||
data['name'])
|
data['name'])
|
||||||
LOG.debug(msg)
|
LOG.debug(msg)
|
||||||
|
@ -97,7 +98,7 @@ class CreateProviderNetwork(forms.SelfHandlingForm):
|
||||||
return network
|
return network
|
||||||
except neutron_exceptions.NeutronClientException as e:
|
except neutron_exceptions.NeutronClientException as e:
|
||||||
redirect = reverse('horizon:admin:providernets:index')
|
redirect = reverse('horizon:admin:providernets:index')
|
||||||
exceptions.handle(request, e.message, redirect=redirect)
|
exceptions.handle(request, str(e), redirect=redirect)
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:admin:providernets:index')
|
redirect = reverse('horizon:admin:providernets:index')
|
||||||
msg = _('Failed to create provider network %s') % data['name']
|
msg = _('Failed to create provider network %s') % data['name']
|
||||||
|
@ -148,7 +149,7 @@ class UpdateProviderNetwork(forms.SelfHandlingForm):
|
||||||
msg = _('Failed to update provider network %s') % data['name']
|
msg = _('Failed to update provider network %s') % data['name']
|
||||||
LOG.info(msg)
|
LOG.info(msg)
|
||||||
redirect = reverse(self.failure_url)
|
redirect = reverse(self.failure_url)
|
||||||
exceptions.handle(request, e.message, redirect=redirect)
|
exceptions.handle(request, str(e), redirect=redirect)
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _('Failed to update provider network %s') % data['name']
|
msg = _('Failed to update provider network %s') % data['name']
|
||||||
LOG.info(msg)
|
LOG.info(msg)
|
||||||
|
|
|
@ -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-2015,2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,11 +145,11 @@ class CreateProviderNetworkRange(forms.SelfHandlingForm):
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
return providernet_range
|
return providernet_range
|
||||||
except neutron_exceptions.NeutronClientException as e:
|
except neutron_exceptions.NeutronClientException as e:
|
||||||
LOG.info(e.message)
|
LOG.info(str(e))
|
||||||
redirect = reverse('horizon:admin:providernets:providernets:'
|
redirect = reverse('horizon:admin:providernets:providernets:'
|
||||||
'detail',
|
'detail',
|
||||||
args=(data['providernet_id'],))
|
args=(data['providernet_id'],))
|
||||||
exceptions.handle(request, e.message, redirect=redirect)
|
exceptions.handle(request, str(e), redirect=redirect)
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _('Failed to create a provider'
|
msg = _('Failed to create a provider'
|
||||||
' network range for network %s') \
|
' network range for network %s') \
|
||||||
|
@ -236,11 +236,11 @@ class UpdateProviderNetworkRange(forms.SelfHandlingForm):
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
return providernet_range
|
return providernet_range
|
||||||
except neutron_exceptions.NeutronClientException as e:
|
except neutron_exceptions.NeutronClientException as e:
|
||||||
LOG.info(e.message)
|
LOG.info(str(e))
|
||||||
redirect = reverse('horizon:admin:providernets:providernets:'
|
redirect = reverse('horizon:admin:providernets:providernets:'
|
||||||
'detail',
|
'detail',
|
||||||
args=(data['providernet_id'],))
|
args=(data['providernet_id'],))
|
||||||
exceptions.handle(request, e.message, redirect=redirect)
|
exceptions.handle(request, str(e), redirect=redirect)
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = (_('Failed to update provider network range %s') %
|
msg = (_('Failed to update provider network range %s') %
|
||||||
data['providernet_range_id'])
|
data['providernet_range_id'])
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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,2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,8 +59,9 @@ class DeleteProviderNetworkRange(tables.DeleteAction):
|
||||||
try:
|
try:
|
||||||
stx_api.neutron.provider_network_range_delete(request, obj_id)
|
stx_api.neutron.provider_network_range_delete(request, obj_id)
|
||||||
except neutron_exceptions.NeutronClientException as e:
|
except neutron_exceptions.NeutronClientException as e:
|
||||||
LOG.info(e.message)
|
LOG.info(str(e))
|
||||||
exceptions.handle(request, e.message,
|
exceptions.handle(request,
|
||||||
|
str(e),
|
||||||
redirect=self.get_redirect_url())
|
redirect=self.get_redirect_url())
|
||||||
except Exception:
|
except Exception:
|
||||||
msg = _('Failed to delete provider network range %s') % obj_id
|
msg = _('Failed to delete provider network range %s') % obj_id
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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-2016 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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-2015 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2012 NEC Corporation
|
# Copyright 2012 NEC Corporation
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
@ -14,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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,8 +49,8 @@ class CreateView(forms.ModalFormView):
|
||||||
if not hasattr(self, "_object"):
|
if not hasattr(self, "_object"):
|
||||||
try:
|
try:
|
||||||
providernet_id = self.kwargs["providernet_id"]
|
providernet_id = self.kwargs["providernet_id"]
|
||||||
self._object = stx_api.neutron.provider_network_get(self.request,
|
self._object = stx_api.neutron.provider_network_get(
|
||||||
providernet_id)
|
self.request, providernet_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse(self.failure_url,
|
redirect = reverse(self.failure_url,
|
||||||
args=(self.kwargs['providernet_id'],))
|
args=(self.kwargs['providernet_id'],))
|
||||||
|
|
|
@ -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-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ class DeleteProviderNetwork(tables.DeleteAction):
|
||||||
try:
|
try:
|
||||||
stx_api.neutron.provider_network_delete(request, obj_id)
|
stx_api.neutron.provider_network_delete(request, obj_id)
|
||||||
except neutron_exceptions.NeutronClientException as e:
|
except neutron_exceptions.NeutronClientException as e:
|
||||||
LOG.info(e.message)
|
LOG.info(str(e))
|
||||||
redirect = reverse('horizon:admin:providernets:index')
|
redirect = reverse('horizon:admin:providernets:index')
|
||||||
exceptions.handle(request, e.message, 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 provider network %s') % obj_id
|
||||||
LOG.info(msg)
|
LOG.info(msg)
|
||||||
|
|
|
@ -1,196 +1,195 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Views for managing volumes.
|
Views for managing volumes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.forms import ValidationError
|
from django.forms import ValidationError
|
||||||
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 forms
|
from horizon import forms
|
||||||
from horizon import messages
|
from horizon import messages
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.api import cinder
|
from openstack_dashboard.api import cinder
|
||||||
from openstack_dashboard.api import nova
|
from openstack_dashboard.dashboards.project.instances import tables
|
||||||
from openstack_dashboard.dashboards.project.instances import tables
|
|
||||||
|
from starlingx_dashboard.api import nova as stx_nova
|
||||||
from starlingx_dashboard.api import nova as stx_nova
|
|
||||||
|
|
||||||
|
class CreateForm(forms.SelfHandlingForm):
|
||||||
class CreateForm(forms.SelfHandlingForm):
|
tenantP = forms.ChoiceField(label=_("Project"), required=True)
|
||||||
tenantP = forms.ChoiceField(label=_("Project"), required=True)
|
name = forms.CharField(max_length="255", label=_("Server Group Name"))
|
||||||
name = forms.CharField(max_length="255", label=_("Server Group Name"))
|
policy = forms.ChoiceField(label=_("Policy"),
|
||||||
policy = forms.ChoiceField(label=_("Policy"),
|
required=False,
|
||||||
required=False,
|
widget=forms.Select(
|
||||||
widget=forms.Select(
|
attrs={
|
||||||
attrs={
|
'class': 'switchable',
|
||||||
'class': 'switchable',
|
'data-slug': 'policy_ht'}))
|
||||||
'data-slug': 'policy_ht'}))
|
|
||||||
|
is_best_effort = forms.BooleanField(label=_("Best Effort"), required=False)
|
||||||
is_best_effort = forms.BooleanField(label=_("Best Effort"), required=False)
|
|
||||||
|
group_size = forms.IntegerField(
|
||||||
group_size = forms.IntegerField(
|
min_value=1,
|
||||||
min_value=1,
|
label=_("Max Group Size (Instances)"),
|
||||||
label=_("Max Group Size (Instances)"),
|
required=False,
|
||||||
required=False,
|
widget=forms.TextInput(
|
||||||
widget=forms.TextInput(
|
attrs={
|
||||||
attrs={
|
'class': 'switchable switched',
|
||||||
'class': 'switchable switched',
|
'data-switch-on': 'policy_ht',
|
||||||
'data-switch-on': 'policy_ht',
|
'data-policy_ht-anti-affinity': 'Max Group Size (Instances)',
|
||||||
'data-policy_ht-anti-affinity': 'Max Group Size (Instances)',
|
'data-policy_ht-affinity': 'Max Group Size (Instances)'}))
|
||||||
'data-policy_ht-affinity': 'Max Group Size (Instances)'}))
|
|
||||||
|
group_size_ht = forms.IntegerField(
|
||||||
group_size_ht = forms.IntegerField(
|
label=_("Max Group Size (Instances)"),
|
||||||
label=_("Max Group Size (Instances)"),
|
required=False,
|
||||||
required=False,
|
widget=forms.TextInput(
|
||||||
widget=forms.TextInput(
|
attrs={
|
||||||
attrs={
|
'readonly': 'readonly',
|
||||||
'readonly': 'readonly',
|
'class': 'switchable switched',
|
||||||
'class': 'switchable switched',
|
'data-switch-on': 'policy_ht',
|
||||||
'data-switch-on': 'policy_ht',
|
'data-policy_ht-affinity-hyperthread':
|
||||||
'data-policy_ht-affinity-hyperthread':
|
'Max Group Size (Instances)'}))
|
||||||
'Max Group Size (Instances)'}))
|
|
||||||
|
def __init__(self, request, *args, **kwargs):
|
||||||
def __init__(self, request, *args, **kwargs):
|
super(CreateForm, self).__init__(request, *args, **kwargs)
|
||||||
super(CreateForm, self).__init__(request, *args, **kwargs)
|
self.fields['policy'].choices = [("anti-affinity", "anti-affinity"),
|
||||||
self.fields['policy'].choices = [("anti-affinity", "anti-affinity"),
|
("affinity", "affinity")]
|
||||||
("affinity", "affinity")]
|
|
||||||
|
# Populate available project_id/name choices
|
||||||
# Populate available project_id/name choices
|
all_projects = []
|
||||||
all_projects = []
|
try:
|
||||||
try:
|
# Get list of available projects.
|
||||||
# Get list of available projects.
|
all_projects, has_more = api.keystone.tenant_list(request)
|
||||||
all_projects, has_more = api.keystone.tenant_list(request)
|
|
||||||
|
projects_list = [(project.id, project.name)
|
||||||
projects_list = [(project.id, project.name)
|
for project in all_projects]
|
||||||
for project in all_projects]
|
|
||||||
|
except Exception:
|
||||||
except Exception:
|
projects_list = []
|
||||||
projects_list = []
|
exceptions.handle(self.request,
|
||||||
exceptions.handle(self.request,
|
_('Unable to retrieve list of tenants.'))
|
||||||
_('Unable to retrieve list of tenants.'))
|
|
||||||
|
self.fields['tenantP'].choices = projects_list
|
||||||
self.fields['tenantP'].choices = projects_list
|
|
||||||
|
def handle(self, request, data):
|
||||||
def handle(self, request, data):
|
try:
|
||||||
try:
|
policy = data['policy']
|
||||||
policy = data['policy']
|
policies = []
|
||||||
policies = []
|
if policy:
|
||||||
if policy:
|
policies.append(policy)
|
||||||
policies.append(policy)
|
metadata = {}
|
||||||
metadata = {}
|
if data['is_best_effort']:
|
||||||
if data['is_best_effort']:
|
metadata['wrs-sg:best_effort'] = "true"
|
||||||
metadata['wrs-sg:best_effort'] = "true"
|
group_size = data['group_size']
|
||||||
group_size = data['group_size']
|
group_size_ht = data['group_size_ht']
|
||||||
group_size_ht = data['group_size_ht']
|
if group_size:
|
||||||
if group_size:
|
metadata['wrs-sg:group_size'] = str(group_size)
|
||||||
metadata['wrs-sg:group_size'] = str(group_size)
|
elif group_size_ht:
|
||||||
elif group_size_ht:
|
metadata['wrs-sg:group_size'] = str(group_size_ht)
|
||||||
metadata['wrs-sg:group_size'] = str(group_size_ht)
|
|
||||||
|
project_id = None
|
||||||
project_id = None
|
if data['tenantP']:
|
||||||
if data['tenantP']:
|
project_id = data['tenantP']
|
||||||
project_id = data['tenantP']
|
|
||||||
|
server_group = stx_nova.server_group_create(
|
||||||
server_group = stx_nova.server_group_create(
|
request, data['name'], project_id, metadata, policies)
|
||||||
request, data['name'], project_id, metadata, policies)
|
return server_group
|
||||||
return server_group
|
|
||||||
|
except ValidationError as e:
|
||||||
except ValidationError as e:
|
self.api_error(e.messages[0])
|
||||||
self.api_error(e.messages[0])
|
return False
|
||||||
return False
|
except Exception as e:
|
||||||
except Exception as e:
|
exceptions.handle(request, ignore=True)
|
||||||
exceptions.handle(request, ignore=True)
|
self.api_error(_("Unable to create server group."))
|
||||||
self.api_error(_("Unable to create server group."))
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
|
class AttachForm(forms.SelfHandlingForm):
|
||||||
class AttachForm(forms.SelfHandlingForm):
|
instance = forms.ChoiceField(label=_("Attach to Server Group"),
|
||||||
instance = forms.ChoiceField(label=_("Attach to Server Group"),
|
help_text=_("Select an server group to "
|
||||||
help_text=_("Select an server group to "
|
"attach to."))
|
||||||
"attach to."))
|
device = forms.CharField(label=_("Device Name"))
|
||||||
device = forms.CharField(label=_("Device Name"))
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
def __init__(self, *args, **kwargs):
|
super(AttachForm, self).__init__(*args, **kwargs)
|
||||||
super(AttachForm, self).__init__(*args, **kwargs)
|
|
||||||
|
# Hide the device field if the hypervisor doesn't support it.
|
||||||
# Hide the device field if the hypervisor doesn't support it.
|
hypervisor_features = getattr(settings,
|
||||||
hypervisor_features = getattr(settings,
|
"OPENSTACK_HYPERVISOR_FEATURES", {})
|
||||||
"OPENSTACK_HYPERVISOR_FEATURES", {})
|
can_set_mount_point = hypervisor_features.get("can_set_mount_point",
|
||||||
can_set_mount_point = hypervisor_features.get("can_set_mount_point",
|
True)
|
||||||
True)
|
if not can_set_mount_point:
|
||||||
if not can_set_mount_point:
|
self.fields['device'].widget = forms.widgets.HiddenInput()
|
||||||
self.fields['device'].widget = forms.widgets.HiddenInput()
|
self.fields['device'].required = False
|
||||||
self.fields['device'].required = False
|
|
||||||
|
# populate volume_id
|
||||||
# populate volume_id
|
volume = kwargs.get('initial', {}).get("volume", None)
|
||||||
volume = kwargs.get('initial', {}).get("volume", None)
|
if volume:
|
||||||
if volume:
|
volume_id = volume.id
|
||||||
volume_id = volume.id
|
else:
|
||||||
else:
|
volume_id = None
|
||||||
volume_id = None
|
self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
|
||||||
self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
|
initial=volume_id)
|
||||||
initial=volume_id)
|
|
||||||
|
# Populate instance choices
|
||||||
# Populate instance choices
|
instance_list = kwargs.get('initial', {}).get('instances', [])
|
||||||
instance_list = kwargs.get('initial', {}).get('instances', [])
|
instances = []
|
||||||
instances = []
|
for instance in instance_list:
|
||||||
for instance in instance_list:
|
if instance.status in tables.ACTIVE_STATES and \
|
||||||
if instance.status in tables.ACTIVE_STATES and \
|
not any(instance.id == att["server_id"]
|
||||||
not any(instance.id == att["server_id"]
|
for att in volume.attachments):
|
||||||
for att in volume.attachments):
|
instances.append((instance.id, '%s (%s)' % (instance.name,
|
||||||
instances.append((instance.id, '%s (%s)' % (instance.name,
|
instance.id)))
|
||||||
instance.id)))
|
if instances:
|
||||||
if instances:
|
instances.insert(0, ("", _("Select an instance")))
|
||||||
instances.insert(0, ("", _("Select an instance")))
|
else:
|
||||||
else:
|
instances = (("", _("No instances available")),)
|
||||||
instances = (("", _("No instances available")),)
|
self.fields['instance'].choices = instances
|
||||||
self.fields['instance'].choices = instances
|
|
||||||
|
def handle(self, request, data):
|
||||||
def handle(self, request, data):
|
instance_choices = dict(self.fields['instance'].choices)
|
||||||
instance_choices = dict(self.fields['instance'].choices)
|
instance_name = instance_choices.get(data['instance'],
|
||||||
instance_name = instance_choices.get(data['instance'],
|
_("Unknown instance (None)"))
|
||||||
_("Unknown instance (None)"))
|
# The name of the instance in the choices list has the ID appended to
|
||||||
# The name of the instance in the choices list has the ID appended to
|
# it, so let's slice that off...
|
||||||
# it, so let's slice that off...
|
instance_name = instance_name.rsplit(" (")[0]
|
||||||
instance_name = instance_name.rsplit(" (")[0]
|
try:
|
||||||
try:
|
attach = api.nova.instance_volume_attach(request,
|
||||||
attach = api.nova.instance_volume_attach(request,
|
data['volume_id'],
|
||||||
data['volume_id'],
|
data['instance'],
|
||||||
data['instance'],
|
data.get('device', ''))
|
||||||
data.get('device', ''))
|
volume = cinder.volume_get(request, data['volume_id'])
|
||||||
volume = cinder.volume_get(request, data['volume_id'])
|
if not volume.display_name:
|
||||||
if not volume.display_name:
|
volume_name = volume.id
|
||||||
volume_name = volume.id
|
else:
|
||||||
else:
|
volume_name = volume.display_name
|
||||||
volume_name = volume.display_name
|
message = _('Attaching volume %(vol)s to instance '
|
||||||
message = _('Attaching volume %(vol)s to instance '
|
'%(inst)s on %(dev)s.') % {"vol": volume_name,
|
||||||
'%(inst)s on %(dev)s.') % {"vol": volume_name,
|
"inst": instance_name,
|
||||||
"inst": instance_name,
|
"dev": attach.device}
|
||||||
"dev": attach.device}
|
messages.info(request, message)
|
||||||
messages.info(request, message)
|
return True
|
||||||
return True
|
except Exception:
|
||||||
except Exception:
|
redirect = reverse("horizon:project:volumes:index")
|
||||||
redirect = reverse("horizon:project:volumes:index")
|
exceptions.handle(request,
|
||||||
exceptions.handle(request,
|
_('Unable to attach volume.'),
|
||||||
_('Unable to attach volume.'),
|
redirect=redirect)
|
||||||
redirect=redirect)
|
|
||||||
|
|
|
@ -1,40 +1,40 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
import horizon
|
import horizon
|
||||||
|
|
||||||
|
|
||||||
class ServerGroups(horizon.Panel):
|
class ServerGroups(horizon.Panel):
|
||||||
name = _("Server Groups")
|
name = _("Server Groups")
|
||||||
slug = 'server_groups'
|
slug = 'server_groups'
|
||||||
# Server groups are wrs-specific
|
# Server groups are wrs-specific
|
||||||
permissions = ('openstack.services.compute',)
|
permissions = ('openstack.services.compute',)
|
||||||
policy_rules = (("compute", "context_is_admin"),)
|
policy_rules = (("compute", "context_is_admin"),)
|
||||||
|
|
||||||
def allowed(self, context):
|
def allowed(self, context):
|
||||||
if context['request'].user.services_region == 'SystemController':
|
if context['request'].user.services_region == 'SystemController':
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return super(ServerGroups, self).allowed(context)
|
return super(ServerGroups, 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':
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -13,7 +13,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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.core.urlresolvers import NoReverseMatch
|
from django.core.urlresolvers import NoReverseMatch
|
||||||
|
@ -28,7 +28,6 @@ from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.api import nova
|
|
||||||
from openstack_dashboard.dashboards.project.volumes.tables \
|
from openstack_dashboard.dashboards.project.volumes.tables \
|
||||||
import get_attachment_name
|
import get_attachment_name
|
||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
|
@ -1,53 +1,53 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
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 openstack_dashboard.api import nova
|
from openstack_dashboard.api import nova
|
||||||
|
|
||||||
from starlingx_dashboard.api import nova as stx_nova
|
from starlingx_dashboard.api import nova as stx_nova
|
||||||
|
|
||||||
|
|
||||||
class OverviewTab(tabs.Tab):
|
class OverviewTab(tabs.Tab):
|
||||||
name = _("Overview")
|
name = _("Overview")
|
||||||
slug = "overview"
|
slug = "overview"
|
||||||
template_name = ("admin/server_groups/"
|
template_name = ("admin/server_groups/"
|
||||||
"_detail_overview.html")
|
"_detail_overview.html")
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
server_group_id = self.tab_group.kwargs['server_group_id']
|
server_group_id = self.tab_group.kwargs['server_group_id']
|
||||||
try:
|
try:
|
||||||
server_group = stx_nova.server_group_get(request, server_group_id)
|
server_group = stx_nova.server_group_get(request, server_group_id)
|
||||||
server_group.members_display = []
|
server_group.members_display = []
|
||||||
for member in server_group.members:
|
for member in server_group.members:
|
||||||
server_group.members_display.append(
|
server_group.members_display.append(
|
||||||
dict(id=member, instance=nova.server_get(request, member)))
|
dict(id=member, instance=nova.server_get(request, member)))
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:admin:server_groups:index')
|
redirect = reverse('horizon:admin:server_groups:index')
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve server group details.'),
|
_('Unable to retrieve server group details.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
return {'server_group': server_group}
|
return {'server_group': server_group}
|
||||||
|
|
||||||
|
|
||||||
class ServerGroupDetailTabs(tabs.TabGroup):
|
class ServerGroupDetailTabs(tabs.TabGroup):
|
||||||
slug = "server_group_details"
|
slug = "server_group_details"
|
||||||
tabs = (OverviewTab,)
|
tabs = (OverviewTab,)
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from starlingx_dashboard.dashboards.admin.server_groups import views
|
from starlingx_dashboard.dashboards.admin.server_groups import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
url(r'^create/$', views.CreateView.as_view(), name='create'),
|
url(r'^create/$', views.CreateView.as_view(), name='create'),
|
||||||
url(r'^(?P<server_group_id>[^/]+)/attach/$',
|
url(r'^(?P<server_group_id>[^/]+)/attach/$',
|
||||||
views.EditAttachmentsView.as_view(),
|
views.EditAttachmentsView.as_view(),
|
||||||
name='attach'),
|
name='attach'),
|
||||||
url(r'^(?P<server_group_id>[^/]+)/$',
|
url(r'^(?P<server_group_id>[^/]+)/$',
|
||||||
views.DetailView.as_view(),
|
views.DetailView.as_view(),
|
||||||
name='detail')
|
name='detail')
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,148 +1,148 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Views for managing server groups.
|
Views for managing server groups.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse_lazy # noqa
|
from django.core.urlresolvers import reverse_lazy # noqa
|
||||||
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 forms
|
from horizon import forms
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
from starlingx_dashboard import api as stx_api
|
from starlingx_dashboard import api as stx_api
|
||||||
from starlingx_dashboard.dashboards.admin.server_groups \
|
from starlingx_dashboard.dashboards.admin.server_groups \
|
||||||
import forms as admin_forms
|
import forms as admin_forms
|
||||||
|
|
||||||
from starlingx_dashboard.dashboards.admin.server_groups \
|
from starlingx_dashboard.dashboards.admin.server_groups \
|
||||||
import tables as admin_tables
|
import tables as admin_tables
|
||||||
from starlingx_dashboard.dashboards.admin.server_groups \
|
from starlingx_dashboard.dashboards.admin.server_groups \
|
||||||
import tabs as admin_tabs
|
import tabs as admin_tabs
|
||||||
|
|
||||||
|
|
||||||
# server groups don't currently support pagination
|
# server groups don't currently support pagination
|
||||||
class IndexView(tables.DataTableView):
|
class IndexView(tables.DataTableView):
|
||||||
table_class = admin_tables.ServerGroupsTable
|
table_class = admin_tables.ServerGroupsTable
|
||||||
template_name = 'admin/server_groups/index.html'
|
template_name = 'admin/server_groups/index.html'
|
||||||
page_title = _("Server Groups")
|
page_title = _("Server Groups")
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
try:
|
try:
|
||||||
server_groups = stx_api.nova.server_group_list(
|
server_groups = stx_api.nova.server_group_list(
|
||||||
self.request, all_projects=True)
|
self.request, all_projects=True)
|
||||||
except Exception:
|
except Exception:
|
||||||
server_groups = []
|
server_groups = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve server groups.'))
|
_('Unable to retrieve server groups.'))
|
||||||
return server_groups
|
return server_groups
|
||||||
|
|
||||||
|
|
||||||
class DetailView(tabs.TabView):
|
class DetailView(tabs.TabView):
|
||||||
tab_group_class = admin_tabs.ServerGroupDetailTabs
|
tab_group_class = admin_tabs.ServerGroupDetailTabs
|
||||||
template_name = 'admin/server_groups/detail.html'
|
template_name = 'admin/server_groups/detail.html'
|
||||||
page_title = 'Server Group Details'
|
page_title = 'Server Group Details'
|
||||||
|
|
||||||
|
|
||||||
class CreateView(forms.ModalFormView):
|
class CreateView(forms.ModalFormView):
|
||||||
form_class = admin_forms.CreateForm
|
form_class = admin_forms.CreateForm
|
||||||
template_name = 'admin/server_groups/create.html'
|
template_name = 'admin/server_groups/create.html'
|
||||||
success_url = reverse_lazy("horizon:admin:server_groups:index")
|
success_url = reverse_lazy("horizon:admin:server_groups:index")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CreateView, self).get_context_data(**kwargs)
|
context = super(CreateView, self).get_context_data(**kwargs)
|
||||||
try:
|
try:
|
||||||
context['usages'] = quotas.tenant_limit_usages(self.request)
|
context['usages'] = quotas.tenant_limit_usages(self.request)
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(self.request)
|
exceptions.handle(self.request)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
|
class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
|
||||||
table_class = admin_tables.AttachmentsTable
|
table_class = admin_tables.AttachmentsTable
|
||||||
form_class = admin_forms.AttachForm
|
form_class = admin_forms.AttachForm
|
||||||
template_name = 'admin/server_groups/attach.html'
|
template_name = 'admin/server_groups/attach.html'
|
||||||
success_url = reverse_lazy("horizon:admin:server_groups:index")
|
success_url = reverse_lazy("horizon:admin:server_groups:index")
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
if not hasattr(self, "_object"):
|
if not hasattr(self, "_object"):
|
||||||
volume_id = self.kwargs['volume_id']
|
volume_id = self.kwargs['volume_id']
|
||||||
try:
|
try:
|
||||||
self._object = api.cinder.volume_get(self.request, volume_id)
|
self._object = api.cinder.volume_get(self.request, volume_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
self._object = None
|
self._object = None
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve volume information.'))
|
_('Unable to retrieve volume information.'))
|
||||||
return self._object
|
return self._object
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
try:
|
try:
|
||||||
volumes = self.get_object()
|
volumes = self.get_object()
|
||||||
attachments = [att for att in volumes.attachments if att]
|
attachments = [att for att in volumes.attachments if att]
|
||||||
except Exception:
|
except Exception:
|
||||||
attachments = []
|
attachments = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve volume information.'))
|
_('Unable to retrieve volume information.'))
|
||||||
return attachments
|
return attachments
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
try:
|
try:
|
||||||
instances, has_more = api.nova.server_list(self.request)
|
instances, has_more = api.nova.server_list(self.request)
|
||||||
except Exception:
|
except Exception:
|
||||||
instances = []
|
instances = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_("Unable to retrieve attachment information."))
|
_("Unable to retrieve attachment information."))
|
||||||
return {'volume': self.get_object(),
|
return {'volume': self.get_object(),
|
||||||
'instances': instances}
|
'instances': instances}
|
||||||
|
|
||||||
def get_form(self):
|
def get_form(self):
|
||||||
if not hasattr(self, "_form"):
|
if not hasattr(self, "_form"):
|
||||||
form_class = self.get_form_class()
|
form_class = self.get_form_class()
|
||||||
self._form = super(EditAttachmentsView, self).get_form(form_class)
|
self._form = super(EditAttachmentsView, self).get_form(form_class)
|
||||||
return self._form
|
return self._form
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(EditAttachmentsView, self).get_context_data(**kwargs)
|
context = super(EditAttachmentsView, self).get_context_data(**kwargs)
|
||||||
context['form'] = self.get_form()
|
context['form'] = self.get_form()
|
||||||
volume = self.get_object()
|
volume = self.get_object()
|
||||||
if volume and volume.status == 'available':
|
if volume and volume.status == 'available':
|
||||||
context['show_attach'] = True
|
context['show_attach'] = True
|
||||||
else:
|
else:
|
||||||
context['show_attach'] = False
|
context['show_attach'] = False
|
||||||
context['volume'] = volume
|
context['volume'] = volume
|
||||||
if self.request.is_ajax():
|
if self.request.is_ajax():
|
||||||
context['hide'] = True
|
context['hide'] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Table action handling
|
# Table action handling
|
||||||
handled = self.construct_tables()
|
handled = self.construct_tables()
|
||||||
if handled:
|
if handled:
|
||||||
return handled
|
return handled
|
||||||
return self.render_to_response(self.get_context_data(**kwargs))
|
return self.render_to_response(self.get_context_data(**kwargs))
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
return self.get(request, *args, **kwargs)
|
return self.get(request, *args, **kwargs)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2016 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -57,7 +57,7 @@ class ApplyPatch(tables.BatchAction):
|
||||||
result = stx_api.patch.patch_apply_req(request, obj_ids)
|
result = stx_api.patch.patch_apply_req(request, obj_ids)
|
||||||
messages.success(request, result)
|
messages.success(request, result)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class RemovePatch(tables.BatchAction):
|
class RemovePatch(tables.BatchAction):
|
||||||
|
@ -97,7 +97,7 @@ class RemovePatch(tables.BatchAction):
|
||||||
result = stx_api.patch.patch_remove_req(request, obj_ids)
|
result = stx_api.patch.patch_remove_req(request, obj_ids)
|
||||||
messages.success(request, result)
|
messages.success(request, result)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class DeletePatch(tables.BatchAction):
|
class DeletePatch(tables.BatchAction):
|
||||||
|
@ -131,7 +131,7 @@ class DeletePatch(tables.BatchAction):
|
||||||
result = stx_api.patch.patch_delete_req(request, obj_ids)
|
result = stx_api.patch.patch_delete_req(request, obj_ids)
|
||||||
messages.success(request, result)
|
messages.success(request, result)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class UpdatePatchRow(tables.Row):
|
class UpdatePatchRow(tables.Row):
|
||||||
|
@ -223,7 +223,8 @@ class CreateStrategy(tables.LinkAction):
|
||||||
def allowed(self, request, datum):
|
def allowed(self, request, datum):
|
||||||
try:
|
try:
|
||||||
# Only a single strategy (patch or upgrade) can exist at a time.
|
# Only a single strategy (patch or upgrade) can exist at a time.
|
||||||
strategy = get_cached_strategy(request, stx_api.vim.STRATEGY_SW_PATCH,
|
strategy = get_cached_strategy(request,
|
||||||
|
stx_api.vim.STRATEGY_SW_PATCH,
|
||||||
self.table)
|
self.table)
|
||||||
if not strategy:
|
if not strategy:
|
||||||
strategy = get_cached_strategy(request,
|
strategy = get_cached_strategy(request,
|
||||||
|
@ -290,7 +291,7 @@ class DeleteStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy delete failed")
|
messages.error(request, "Strategy delete failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class DeletePatchStrategy(DeleteStrategy):
|
class DeletePatchStrategy(DeleteStrategy):
|
||||||
|
@ -338,7 +339,7 @@ class ApplyStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy apply failed")
|
messages.error(request, "Strategy apply failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class ApplyPatchStrategy(ApplyStrategy):
|
class ApplyPatchStrategy(ApplyStrategy):
|
||||||
|
@ -387,7 +388,7 @@ class AbortStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy abort failed")
|
messages.error(request, "Strategy abort failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class AbortPatchStrategy(AbortStrategy):
|
class AbortPatchStrategy(AbortStrategy):
|
||||||
|
@ -442,7 +443,8 @@ class ApplyStage(tables.BatchAction):
|
||||||
for obj_id in obj_ids:
|
for obj_id in obj_ids:
|
||||||
try:
|
try:
|
||||||
stage_id = obj_id.split('-', 1)[1]
|
stage_id = obj_id.split('-', 1)[1]
|
||||||
result = stx_api.vim.apply_strategy(request, self.strategy_name,
|
result = stx_api.vim.apply_strategy(request,
|
||||||
|
self.strategy_name,
|
||||||
stage_id)
|
stage_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
messages.error(request, "Strategy stage %s apply failed" %
|
messages.error(request, "Strategy stage %s apply failed" %
|
||||||
|
@ -453,7 +455,7 @@ class ApplyStage(tables.BatchAction):
|
||||||
stage_id)
|
stage_id)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class ApplyPatchStage(ApplyStage):
|
class ApplyPatchStage(ApplyStage):
|
||||||
|
@ -503,7 +505,8 @@ class AbortStage(tables.BatchAction):
|
||||||
for obj_id in obj_ids:
|
for obj_id in obj_ids:
|
||||||
try:
|
try:
|
||||||
stage_id = obj_id.split('-', 1)[1]
|
stage_id = obj_id.split('-', 1)[1]
|
||||||
result = stx_api.vim.abort_strategy(request, self.strategy_name,
|
result = stx_api.vim.abort_strategy(request,
|
||||||
|
self.strategy_name,
|
||||||
stage_id)
|
stage_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
messages.error(request,
|
messages.error(request,
|
||||||
|
@ -514,7 +517,7 @@ class AbortStage(tables.BatchAction):
|
||||||
stage_id)
|
stage_id)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class AbortPatchStage(AbortStage):
|
class AbortPatchStage(AbortStage):
|
||||||
|
@ -598,7 +601,10 @@ class UpdateStageRow(tables.Row):
|
||||||
def get_data(self, request, row_id):
|
def get_data(self, request, row_id):
|
||||||
phase = row_id.split('-', 1)[0]
|
phase = row_id.split('-', 1)[0]
|
||||||
stage_id = row_id.split('-', 1)[1]
|
stage_id = row_id.split('-', 1)[1]
|
||||||
stage = stx_api.vim.get_stage(request, self.strategy_name, phase, stage_id)
|
stage = stx_api.vim.get_stage(request,
|
||||||
|
self.strategy_name,
|
||||||
|
phase,
|
||||||
|
stage_id)
|
||||||
return stage
|
return stage
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2016 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -62,7 +62,8 @@ class PatchOrchestrationTab(tabs.TableTab):
|
||||||
|
|
||||||
strategy = None
|
strategy = None
|
||||||
try:
|
try:
|
||||||
strategy = stx_api.vim.get_strategy(request, stx_api.vim.STRATEGY_SW_PATCH)
|
strategy = stx_api.vim.get_strategy(request,
|
||||||
|
stx_api.vim.STRATEGY_SW_PATCH)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
exceptions.handle(request,
|
exceptions.handle(request,
|
||||||
|
@ -75,7 +76,8 @@ class PatchOrchestrationTab(tabs.TableTab):
|
||||||
request = self.request
|
request = self.request
|
||||||
stages = []
|
stages = []
|
||||||
try:
|
try:
|
||||||
stages = stx_api.vim.get_stages(request, stx_api.vim.STRATEGY_SW_PATCH)
|
stages = stx_api.vim.get_stages(request,
|
||||||
|
stx_api.vim.STRATEGY_SW_PATCH)
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve stages list.'))
|
_('Unable to retrieve stages list.'))
|
||||||
|
@ -100,8 +102,8 @@ class UpgradeOrchestrationTab(tabs.TableTab):
|
||||||
|
|
||||||
strategy = None
|
strategy = None
|
||||||
try:
|
try:
|
||||||
strategy = stx_api.vim.get_strategy(request,
|
strategy = stx_api.vim.get_strategy(
|
||||||
stx_api.vim.STRATEGY_SW_UPGRADE)
|
request, stx_api.vim.STRATEGY_SW_UPGRADE)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
exceptions.handle(request,
|
exceptions.handle(request,
|
||||||
|
@ -114,7 +116,8 @@ class UpgradeOrchestrationTab(tabs.TableTab):
|
||||||
request = self.request
|
request = self.request
|
||||||
stages = []
|
stages = []
|
||||||
try:
|
try:
|
||||||
stages = stx_api.vim.get_stages(request, stx_api.vim.STRATEGY_SW_UPGRADE)
|
stages = stx_api.vim.get_stages(request,
|
||||||
|
stx_api.vim.STRATEGY_SW_UPGRADE)
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve stages list.'))
|
_('Unable to retrieve stages list.'))
|
||||||
|
|
|
@ -17,8 +17,6 @@ from horizon import exceptions
|
||||||
from horizon import forms
|
from horizon import forms
|
||||||
from horizon import messages
|
from horizon import messages
|
||||||
|
|
||||||
from openstack_dashboard import api
|
|
||||||
|
|
||||||
from starlingx_dashboard import api as stx_api
|
from starlingx_dashboard import api as stx_api
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -904,9 +902,8 @@ class UpdateiStoragePools(forms.SelfHandlingForm):
|
||||||
LOG.debug(data)
|
LOG.debug(data)
|
||||||
|
|
||||||
if send_to_sysinv:
|
if send_to_sysinv:
|
||||||
my_storage = stx_api.sysinv.storpool_update(request,
|
my_storage = stx_api.sysinv.storpool_update(
|
||||||
storage_config_uuid,
|
request, storage_config_uuid, **data)
|
||||||
**data)
|
|
||||||
|
|
||||||
if my_storage:
|
if my_storage:
|
||||||
msg = _(
|
msg = _(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
@ -11,8 +11,6 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
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.system_config.address_pools import \
|
from starlingx_dashboard.dashboards.admin.system_config.address_pools import \
|
||||||
tables as address_pool_tables
|
tables as address_pool_tables
|
||||||
|
|
|
@ -15,8 +15,6 @@ from horizon import forms
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
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.system_config.forms \
|
from starlingx_dashboard.dashboards.admin.system_config.forms \
|
||||||
import CreateSDNController
|
import CreateSDNController
|
||||||
|
@ -432,8 +430,8 @@ class UpdateSDNControllerView(forms.ModalFormView):
|
||||||
if not hasattr(self, "_object"):
|
if not hasattr(self, "_object"):
|
||||||
controller_uuid = self.kwargs['uuid']
|
controller_uuid = self.kwargs['uuid']
|
||||||
try:
|
try:
|
||||||
self._object = stx_api.sysinv.sdn_controller_get(self.request,
|
self._object = stx_api.sysinv.sdn_controller_get(
|
||||||
controller_uuid)
|
self.request, controller_uuid)
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = self.success_url
|
redirect = self.success_url
|
||||||
msg = _('Unable to retrieve SDN controller details.')
|
msg = _('Unable to retrieve SDN controller details.')
|
||||||
|
|
|
@ -30,4 +30,5 @@ class DCAdmin(horizon.Dashboard):
|
||||||
|
|
||||||
return super(DCAdmin, self).allowed(context)
|
return super(DCAdmin, self).allowed(context)
|
||||||
|
|
||||||
|
|
||||||
horizon.register(DCAdmin)
|
horizon.register(DCAdmin)
|
||||||
|
|
|
@ -115,7 +115,7 @@ class DeleteCloudPatchStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy delete failed")
|
messages.error(request, "Strategy delete failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class ApplyCloudPatchStrategy(tables.Action):
|
class ApplyCloudPatchStrategy(tables.Action):
|
||||||
|
@ -151,7 +151,7 @@ class ApplyCloudPatchStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy apply failed")
|
messages.error(request, "Strategy apply failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
class AbortCloudPatchStrategy(tables.Action):
|
class AbortCloudPatchStrategy(tables.Action):
|
||||||
|
@ -190,7 +190,7 @@ class AbortCloudPatchStrategy(tables.Action):
|
||||||
messages.error(request, "Strategy abort failed")
|
messages.error(request, "Strategy abort failed")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
LOG.exception(ex)
|
LOG.exception(ex)
|
||||||
messages.error(request, ex.message)
|
messages.error(request, str(ex))
|
||||||
|
|
||||||
|
|
||||||
STEP_STATE_CHOICES = (
|
STEP_STATE_CHOICES = (
|
||||||
|
|
|
@ -1,180 +1,180 @@
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Views for managing volumes.
|
Views for managing volumes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.forms import ValidationError
|
from django.forms import ValidationError
|
||||||
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 forms
|
from horizon import forms
|
||||||
from horizon import messages
|
from horizon import messages
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.api import cinder
|
from openstack_dashboard.api import cinder
|
||||||
from openstack_dashboard.dashboards.project.instances import tables
|
from openstack_dashboard.dashboards.project.instances import tables
|
||||||
|
|
||||||
from starlingx_dashboard.api import nova as stx_nova
|
from starlingx_dashboard.api import nova as stx_nova
|
||||||
|
|
||||||
|
|
||||||
class CreateForm(forms.SelfHandlingForm):
|
class CreateForm(forms.SelfHandlingForm):
|
||||||
name = forms.CharField(max_length="255", label=_("Server Group Name"))
|
name = forms.CharField(max_length="255", label=_("Server Group Name"))
|
||||||
policy = forms.ChoiceField(label=_("Policy"),
|
policy = forms.ChoiceField(label=_("Policy"),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.Select(
|
widget=forms.Select(
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'switchable',
|
'class': 'switchable',
|
||||||
'data-slug': 'policy_ht'}))
|
'data-slug': 'policy_ht'}))
|
||||||
|
|
||||||
is_best_effort = forms.BooleanField(label=_("Best Effort"), required=False)
|
is_best_effort = forms.BooleanField(label=_("Best Effort"), required=False)
|
||||||
|
|
||||||
group_size = forms.IntegerField(
|
group_size = forms.IntegerField(
|
||||||
min_value=1,
|
min_value=1,
|
||||||
label=_("Max Group Size (Instances)"),
|
label=_("Max Group Size (Instances)"),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'switchable switched',
|
'class': 'switchable switched',
|
||||||
'data-switch-on': 'policy_ht',
|
'data-switch-on': 'policy_ht',
|
||||||
'data-policy_ht-anti-affinity': 'Max Group Size (Instances)',
|
'data-policy_ht-anti-affinity': 'Max Group Size (Instances)',
|
||||||
'data-policy_ht-affinity': 'Max Group Size (Instances)'}))
|
'data-policy_ht-affinity': 'Max Group Size (Instances)'}))
|
||||||
|
|
||||||
group_size_ht = forms.IntegerField(
|
group_size_ht = forms.IntegerField(
|
||||||
label=_("Max Group Size (Instances)"),
|
label=_("Max Group Size (Instances)"),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
attrs={
|
attrs={
|
||||||
'readonly': 'readonly',
|
'readonly': 'readonly',
|
||||||
'class': 'switchable switched',
|
'class': 'switchable switched',
|
||||||
'data-switch-on': 'policy_ht',
|
'data-switch-on': 'policy_ht',
|
||||||
'data-policy_ht-affinity-hyperthread':
|
'data-policy_ht-affinity-hyperthread':
|
||||||
'Max Group Size (Instances)'}))
|
'Max Group Size (Instances)'}))
|
||||||
|
|
||||||
def __init__(self, request, *args, **kwargs):
|
def __init__(self, request, *args, **kwargs):
|
||||||
super(CreateForm, self).__init__(request, *args, **kwargs)
|
super(CreateForm, self).__init__(request, *args, **kwargs)
|
||||||
self.fields['policy'].choices = [("anti-affinity", "anti-affinity"),
|
self.fields['policy'].choices = [("anti-affinity", "anti-affinity"),
|
||||||
("affinity", "affinity")]
|
("affinity", "affinity")]
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
try:
|
try:
|
||||||
project_id = self.request.user.tenant_id
|
project_id = self.request.user.tenant_id
|
||||||
policy = data['policy']
|
policy = data['policy']
|
||||||
policies = []
|
policies = []
|
||||||
if policy:
|
if policy:
|
||||||
policies.append(policy)
|
policies.append(policy)
|
||||||
metadata = {}
|
metadata = {}
|
||||||
if data['is_best_effort']:
|
if data['is_best_effort']:
|
||||||
metadata['wrs-sg:best_effort'] = "true"
|
metadata['wrs-sg:best_effort'] = "true"
|
||||||
group_size = data['group_size']
|
group_size = data['group_size']
|
||||||
group_size_ht = data['group_size_ht']
|
group_size_ht = data['group_size_ht']
|
||||||
if group_size:
|
if group_size:
|
||||||
metadata['wrs-sg:group_size'] = str(group_size)
|
metadata['wrs-sg:group_size'] = str(group_size)
|
||||||
elif group_size_ht:
|
elif group_size_ht:
|
||||||
metadata['wrs-sg:group_size'] = str(group_size_ht)
|
metadata['wrs-sg:group_size'] = str(group_size_ht)
|
||||||
|
|
||||||
kwargs = {'name': data['name'],
|
kwargs = {'name': data['name'],
|
||||||
'policies': policies,
|
'policies': policies,
|
||||||
'metadata': metadata,
|
'metadata': metadata,
|
||||||
'project_id': project_id}
|
'project_id': project_id}
|
||||||
|
|
||||||
server_group = stx_nova.server_group_create(request, **kwargs)
|
server_group = stx_nova.server_group_create(request, **kwargs)
|
||||||
return server_group
|
return server_group
|
||||||
|
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
self.api_error(e.messages[0])
|
self.api_error(e.messages[0])
|
||||||
return False
|
return False
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(request, ignore=True)
|
exceptions.handle(request, ignore=True)
|
||||||
self.api_error(_("Unable to create server group."))
|
self.api_error(_("Unable to create server group."))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class AttachForm(forms.SelfHandlingForm):
|
class AttachForm(forms.SelfHandlingForm):
|
||||||
instance = forms.ChoiceField(label=_("Attach to Server Group"),
|
instance = forms.ChoiceField(label=_("Attach to Server Group"),
|
||||||
help_text=_("Select an server group to "
|
help_text=_("Select an server group to "
|
||||||
"attach to."))
|
"attach to."))
|
||||||
device = forms.CharField(label=_("Device Name"))
|
device = forms.CharField(label=_("Device Name"))
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(AttachForm, self).__init__(*args, **kwargs)
|
super(AttachForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Hide the device field if the hypervisor doesn't support it.
|
# Hide the device field if the hypervisor doesn't support it.
|
||||||
hypervisor_features = getattr(settings,
|
hypervisor_features = getattr(settings,
|
||||||
"OPENSTACK_HYPERVISOR_FEATURES",
|
"OPENSTACK_HYPERVISOR_FEATURES",
|
||||||
{})
|
{})
|
||||||
can_set_mount_point = hypervisor_features.get("can_set_mount_point",
|
can_set_mount_point = hypervisor_features.get("can_set_mount_point",
|
||||||
True)
|
True)
|
||||||
if not can_set_mount_point:
|
if not can_set_mount_point:
|
||||||
self.fields['device'].widget = forms.widgets.HiddenInput()
|
self.fields['device'].widget = forms.widgets.HiddenInput()
|
||||||
self.fields['device'].required = False
|
self.fields['device'].required = False
|
||||||
|
|
||||||
# populate volume_id
|
# populate volume_id
|
||||||
volume = kwargs.get('initial', {}).get("volume", None)
|
volume = kwargs.get('initial', {}).get("volume", None)
|
||||||
if volume:
|
if volume:
|
||||||
volume_id = volume.id
|
volume_id = volume.id
|
||||||
else:
|
else:
|
||||||
volume_id = None
|
volume_id = None
|
||||||
self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
|
self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
|
||||||
initial=volume_id)
|
initial=volume_id)
|
||||||
|
|
||||||
# Populate instance choices
|
# Populate instance choices
|
||||||
instance_list = kwargs.get('initial', {}).get('instances', [])
|
instance_list = kwargs.get('initial', {}).get('instances', [])
|
||||||
instances = []
|
instances = []
|
||||||
for instance in instance_list:
|
for instance in instance_list:
|
||||||
if instance.status in tables.ACTIVE_STATES and \
|
if instance.status in tables.ACTIVE_STATES and \
|
||||||
not any(instance.id == att["server_id"]
|
not any(instance.id == att["server_id"]
|
||||||
for att in volume.attachments):
|
for att in volume.attachments):
|
||||||
instances.append((instance.id, '%s (%s)' % (instance.name,
|
instances.append((instance.id, '%s (%s)' % (instance.name,
|
||||||
instance.id)))
|
instance.id)))
|
||||||
if instances:
|
if instances:
|
||||||
instances.insert(0, ("", _("Select an instance")))
|
instances.insert(0, ("", _("Select an instance")))
|
||||||
else:
|
else:
|
||||||
instances = (("", _("No instances available")),)
|
instances = (("", _("No instances available")),)
|
||||||
self.fields['instance'].choices = instances
|
self.fields['instance'].choices = instances
|
||||||
|
|
||||||
def handle(self, request, data):
|
def handle(self, request, data):
|
||||||
instance_choices = dict(self.fields['instance'].choices)
|
instance_choices = dict(self.fields['instance'].choices)
|
||||||
instance_name = instance_choices.get(data['instance'],
|
instance_name = instance_choices.get(data['instance'],
|
||||||
_("Unknown instance (None)"))
|
_("Unknown instance (None)"))
|
||||||
# The name of the instance in the choices list has the ID appended to
|
# The name of the instance in the choices list has the ID appended to
|
||||||
# it, so let's slice that off...
|
# it, so let's slice that off...
|
||||||
instance_name = instance_name.rsplit(" (")[0]
|
instance_name = instance_name.rsplit(" (")[0]
|
||||||
try:
|
try:
|
||||||
attach = api.nova.instance_volume_attach(request,
|
attach = api.nova.instance_volume_attach(request,
|
||||||
data['volume_id'],
|
data['volume_id'],
|
||||||
data['instance'],
|
data['instance'],
|
||||||
data.get('device', ''))
|
data.get('device', ''))
|
||||||
volume = cinder.volume_get(request, data['volume_id'])
|
volume = cinder.volume_get(request, data['volume_id'])
|
||||||
if not volume.display_name:
|
if not volume.display_name:
|
||||||
volume_name = volume.id
|
volume_name = volume.id
|
||||||
else:
|
else:
|
||||||
volume_name = volume.display_name
|
volume_name = volume.display_name
|
||||||
message = _('Attaching volume %(vol)s to instance '
|
message = _('Attaching volume %(vol)s to instance '
|
||||||
'%(inst)s on %(dev)s.') % {"vol": volume_name,
|
'%(inst)s on %(dev)s.') % {"vol": volume_name,
|
||||||
"inst": instance_name,
|
"inst": instance_name,
|
||||||
"dev": attach.device}
|
"dev": attach.device}
|
||||||
messages.info(request, message)
|
messages.info(request, message)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse("horizon:project:volumes:index")
|
redirect = reverse("horizon:project:volumes:index")
|
||||||
exceptions.handle(request,
|
exceptions.handle(request,
|
||||||
_('Unable to attach volume.'),
|
_('Unable to attach volume.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
|
|
||||||
import horizon
|
import horizon
|
||||||
|
|
||||||
from openstack_dashboard.api import base
|
from openstack_dashboard.api import base
|
||||||
from openstack_dashboard.dashboards.project import dashboard
|
from openstack_dashboard.dashboards.project import dashboard
|
||||||
|
|
||||||
|
|
||||||
class ServerGroups(horizon.Panel):
|
class ServerGroups(horizon.Panel):
|
||||||
name = _("Server Groups")
|
name = _("Server Groups")
|
||||||
slug = 'server_groups'
|
slug = 'server_groups'
|
||||||
# Server groups are wrs-specific
|
# Server groups are wrs-specific
|
||||||
permissions = ('openstack.services.platform',)
|
permissions = ('openstack.services.platform',)
|
||||||
|
|
||||||
def allowed(self, context):
|
def allowed(self, context):
|
||||||
if not base.is_service_enabled(context['request'], 'compute'):
|
if not base.is_service_enabled(context['request'], 'compute'):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return super(ServerGroups, self).allowed(context)
|
return super(ServerGroups, self).allowed(context)
|
||||||
|
|
||||||
def nav(self, context):
|
def nav(self, context):
|
||||||
if not base.is_service_enabled(context['request'], 'compute'):
|
if not base.is_service_enabled(context['request'], 'compute'):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
dashboard.Project.register(ServerGroups)
|
dashboard.Project.register(ServerGroups)
|
||||||
|
|
|
@ -1,287 +1,286 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.core.urlresolvers import NoReverseMatch
|
from django.core.urlresolvers import NoReverseMatch
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils import html
|
from django.utils import html
|
||||||
from django.utils import safestring
|
from django.utils import safestring
|
||||||
from django.utils.translation import string_concat # noqa
|
from django.utils.translation import string_concat # noqa
|
||||||
from django.utils.translation import ugettext_lazy as _ # noqa
|
from django.utils.translation import ugettext_lazy as _ # noqa
|
||||||
from django.utils.translation import ungettext_lazy
|
from django.utils.translation import ungettext_lazy
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.api import nova
|
from openstack_dashboard.dashboards.project.volumes.tables \
|
||||||
from openstack_dashboard.dashboards.project.volumes.tables \
|
import get_attachment_name
|
||||||
import get_attachment_name
|
from openstack_dashboard.usage import quotas
|
||||||
from openstack_dashboard.usage import quotas
|
|
||||||
|
from starlingx_dashboard.api import nova as stx_nova
|
||||||
from starlingx_dashboard.api import nova as stx_nova
|
|
||||||
|
DELETABLE_STATES = ("available", "error")
|
||||||
DELETABLE_STATES = ("available", "error")
|
|
||||||
|
|
||||||
|
class DeleteServerGroup(tables.DeleteAction):
|
||||||
class DeleteServerGroup(tables.DeleteAction):
|
data_type_singular = _("Server Group")
|
||||||
data_type_singular = _("Server Group")
|
data_type_plural = _("Server Groups")
|
||||||
data_type_plural = _("Server Groups")
|
action_past = _("Scheduled deletion of")
|
||||||
action_past = _("Scheduled deletion of")
|
|
||||||
|
@staticmethod
|
||||||
@staticmethod
|
def action_present(count):
|
||||||
def action_present(count):
|
return ungettext_lazy(
|
||||||
return ungettext_lazy(
|
"Delete Server Group",
|
||||||
"Delete Server Group",
|
"Delete Server Groups",
|
||||||
"Delete Server Groups",
|
count
|
||||||
count
|
)
|
||||||
)
|
|
||||||
|
@staticmethod
|
||||||
@staticmethod
|
def action_past(count):
|
||||||
def action_past(count):
|
return ungettext_lazy(
|
||||||
return ungettext_lazy(
|
"Deleted Server Group",
|
||||||
"Deleted Server Group",
|
"Deleted Server Groups",
|
||||||
"Deleted Server Groups",
|
count
|
||||||
count
|
)
|
||||||
)
|
|
||||||
|
def delete(self, request, obj_id):
|
||||||
def delete(self, request, obj_id):
|
obj = self.table.get_object_by_id(obj_id)
|
||||||
obj = self.table.get_object_by_id(obj_id)
|
name = self.table.get_object_display(obj)
|
||||||
name = self.table.get_object_display(obj)
|
|
||||||
|
try:
|
||||||
try:
|
stx_nova.server_group_delete(request, obj_id)
|
||||||
stx_nova.server_group_delete(request, obj_id)
|
except Exception:
|
||||||
except Exception:
|
msg = _('Unable to delete group "%s" because it is not empty. '
|
||||||
msg = _('Unable to delete group "%s" because it is not empty. '
|
'Either delete the member '
|
||||||
'Either delete the member '
|
'instances or remove them from the group.')
|
||||||
'instances or remove them from the group.')
|
exceptions.check_message(["group", "not", "empty."], msg % name)
|
||||||
exceptions.check_message(["group", "not", "empty."], msg % name)
|
raise
|
||||||
raise
|
|
||||||
|
# maybe do a precheck to see if the group is empty first?
|
||||||
# maybe do a precheck to see if the group is empty first?
|
def allowed(self, request, server_group=None):
|
||||||
def allowed(self, request, server_group=None):
|
return True
|
||||||
return True
|
|
||||||
|
|
||||||
|
class CreateServerGroup(tables.LinkAction):
|
||||||
class CreateServerGroup(tables.LinkAction):
|
name = "create"
|
||||||
name = "create"
|
verbose_name = _("Create Server Group")
|
||||||
verbose_name = _("Create Server Group")
|
url = "horizon:project:server_groups:create"
|
||||||
url = "horizon:project:server_groups:create"
|
classes = ("ajax-modal", "btn-create")
|
||||||
classes = ("ajax-modal", "btn-create")
|
icon = "plus"
|
||||||
icon = "plus"
|
|
||||||
|
def allowed(self, request, volume=None):
|
||||||
def allowed(self, request, volume=None):
|
usages = quotas.tenant_quota_usages(request)
|
||||||
usages = quotas.tenant_quota_usages(request)
|
if usages['server_groups']['available'] <= 0:
|
||||||
if usages['server_groups']['available'] <= 0:
|
if "disabled" not in self.classes:
|
||||||
if "disabled" not in self.classes:
|
self.classes = [c for c in self.classes] + ['disabled']
|
||||||
self.classes = [c for c in self.classes] + ['disabled']
|
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
_("(Quota exceeded)"))
|
||||||
_("(Quota exceeded)"))
|
else:
|
||||||
else:
|
self.verbose_name = _("Create Server Group")
|
||||||
self.verbose_name = _("Create Server Group")
|
classes = [c for c in self.classes if c != "disabled"]
|
||||||
classes = [c for c in self.classes if c != "disabled"]
|
self.classes = classes
|
||||||
self.classes = classes
|
return True
|
||||||
return True
|
|
||||||
|
|
||||||
|
class EditAttachments(tables.LinkAction):
|
||||||
class EditAttachments(tables.LinkAction):
|
name = "attachments"
|
||||||
name = "attachments"
|
verbose_name = _("Edit Attachments")
|
||||||
verbose_name = _("Edit Attachments")
|
url = "horizon:project:server_groups:attach"
|
||||||
url = "horizon:project:server_groups:attach"
|
classes = ("ajax-modal", "btn-edit")
|
||||||
classes = ("ajax-modal", "btn-edit")
|
|
||||||
|
def allowed(self, request, server_group=None):
|
||||||
def allowed(self, request, server_group=None):
|
return True # volume.status in ("available", "in-use")
|
||||||
return True # volume.status in ("available", "in-use")
|
|
||||||
|
|
||||||
|
class CreateSnapshot(tables.LinkAction):
|
||||||
class CreateSnapshot(tables.LinkAction):
|
name = "snapshots"
|
||||||
name = "snapshots"
|
verbose_name = _("Create Snapshot")
|
||||||
verbose_name = _("Create Snapshot")
|
url = "horizon:project:server_groups:create_snapshot"
|
||||||
url = "horizon:project:server_groups:create_snapshot"
|
classes = ("ajax-modal", "btn-camera")
|
||||||
classes = ("ajax-modal", "btn-camera")
|
|
||||||
|
def allowed(self, request, server_group=None):
|
||||||
def allowed(self, request, server_group=None):
|
return True # server_group.status == "available"
|
||||||
return True # server_group.status == "available"
|
|
||||||
|
|
||||||
|
class UpdateRow(tables.Row):
|
||||||
class UpdateRow(tables.Row):
|
ajax = True
|
||||||
ajax = True
|
|
||||||
|
def get_data(self, request, server_group_id):
|
||||||
def get_data(self, request, server_group_id):
|
server_group = stx_nova.server_group_get(request, server_group_id)
|
||||||
server_group = stx_nova.server_group_get(request, server_group_id)
|
if not server_group.name:
|
||||||
if not server_group.name:
|
server_group.name = server_group_id
|
||||||
server_group.name = server_group_id
|
return server_group
|
||||||
return server_group
|
|
||||||
|
|
||||||
|
def get_policies(server_group):
|
||||||
def get_policies(server_group):
|
policies = ', '.join(server_group.policies)
|
||||||
policies = ', '.join(server_group.policies)
|
return policies
|
||||||
return policies
|
|
||||||
|
|
||||||
|
def get_metadata(server_group):
|
||||||
def get_metadata(server_group):
|
metadata_items = ['{}:{}'.format(x, y) for x, y in
|
||||||
metadata_items = ['{}:{}'.format(x, y) for x, y in
|
server_group.metadata.items()]
|
||||||
server_group.metadata.items()]
|
metadata = ', '.join(metadata_items)
|
||||||
metadata = ', '.join(metadata_items)
|
return metadata
|
||||||
return metadata
|
|
||||||
|
|
||||||
|
def get_member_name(request, server_id):
|
||||||
def get_member_name(request, server_id):
|
try:
|
||||||
try:
|
server = api.nova.server_get(request, server_id)
|
||||||
server = api.nova.server_get(request, server_id)
|
name = server.name
|
||||||
name = server.name
|
except Exception:
|
||||||
except Exception:
|
name = None
|
||||||
name = None
|
exceptions.handle(request, _("Unable to retrieve "
|
||||||
exceptions.handle(request, _("Unable to retrieve "
|
"member information."))
|
||||||
"member information."))
|
# try and get a URL
|
||||||
# try and get a URL
|
try:
|
||||||
try:
|
url = reverse("horizon:project:instances:detail", args=(server_id,))
|
||||||
url = reverse("horizon:project:instances:detail", args=(server_id,))
|
instance = '<a href="%s">%s</a>' % (url, html.escape(name))
|
||||||
instance = '<a href="%s">%s</a>' % (url, html.escape(name))
|
except NoReverseMatch:
|
||||||
except NoReverseMatch:
|
instance = name
|
||||||
instance = name
|
return instance
|
||||||
return instance
|
|
||||||
|
|
||||||
|
class MemberColumn(tables.Column):
|
||||||
class MemberColumn(tables.Column):
|
"""Customized column class
|
||||||
"""Customized column class
|
|
||||||
|
Customized column class that does complex processing on the instances
|
||||||
Customized column class that does complex processing on the instances
|
in a server group. This was substantially copied
|
||||||
in a server group. This was substantially copied
|
from the volume equivalent.
|
||||||
from the volume equivalent.
|
"""
|
||||||
"""
|
|
||||||
|
def get_raw_data(self, server_group):
|
||||||
def get_raw_data(self, server_group):
|
request = self.table.request
|
||||||
request = self.table.request
|
link = _('%(name)s (%(id)s)')
|
||||||
link = _('%(name)s (%(id)s)')
|
members = []
|
||||||
members = []
|
for member in server_group.members:
|
||||||
for member in server_group.members:
|
member_id = member
|
||||||
member_id = member
|
name = get_member_name(request, member)
|
||||||
name = get_member_name(request, member)
|
vals = {"name": name, "id": member_id}
|
||||||
vals = {"name": name, "id": member_id}
|
members.append(link % vals)
|
||||||
members.append(link % vals)
|
return safestring.mark_safe(", ".join(members))
|
||||||
return safestring.mark_safe(", ".join(members))
|
|
||||||
|
|
||||||
|
def get_server_group_type(server_group):
|
||||||
def get_server_group_type(server_group):
|
return server_group.volume_type if server_group.volume_type != "None" \
|
||||||
return server_group.volume_type if server_group.volume_type != "None" \
|
else None
|
||||||
else None
|
|
||||||
|
|
||||||
|
class ServerGroupsFilterAction(tables.FilterAction):
|
||||||
class ServerGroupsFilterAction(tables.FilterAction):
|
def filter(self, table, server_groups, filter_string):
|
||||||
def filter(self, table, server_groups, filter_string):
|
"""Naive case-insensitive search."""
|
||||||
"""Naive case-insensitive search."""
|
q = filter_string.lower()
|
||||||
q = filter_string.lower()
|
return [group for group in server_groups
|
||||||
return [group for group in server_groups
|
if q in group.display_name.lower()]
|
||||||
if q in group.display_name.lower()]
|
|
||||||
|
|
||||||
|
class ServerGroupsTable(tables.DataTable):
|
||||||
class ServerGroupsTable(tables.DataTable):
|
name = tables.Column("name",
|
||||||
name = tables.Column("name",
|
verbose_name=_("Group Name"),
|
||||||
verbose_name=_("Group Name"),
|
link="horizon:project:server_groups:detail")
|
||||||
link="horizon:project:server_groups:detail")
|
policies = tables.Column(get_policies,
|
||||||
policies = tables.Column(get_policies,
|
verbose_name=_("Policies"))
|
||||||
verbose_name=_("Policies"))
|
members = MemberColumn("members",
|
||||||
members = MemberColumn("members",
|
verbose_name=_("Members"))
|
||||||
verbose_name=_("Members"))
|
metadata = tables.Column(get_metadata,
|
||||||
metadata = tables.Column(get_metadata,
|
verbose_name=_("Metadata"))
|
||||||
verbose_name=_("Metadata"))
|
|
||||||
|
class Meta(object):
|
||||||
class Meta(object):
|
name = "server_groups"
|
||||||
name = "server_groups"
|
verbose_name = _("Server Groups")
|
||||||
verbose_name = _("Server Groups")
|
row_class = UpdateRow
|
||||||
row_class = UpdateRow
|
table_actions = (
|
||||||
table_actions = (
|
CreateServerGroup, DeleteServerGroup, ServerGroupsFilterAction)
|
||||||
CreateServerGroup, DeleteServerGroup, ServerGroupsFilterAction)
|
row_actions = (DeleteServerGroup,)
|
||||||
row_actions = (DeleteServerGroup,)
|
|
||||||
|
def get_object_display(self, obj):
|
||||||
def get_object_display(self, obj):
|
return obj.name
|
||||||
return obj.name
|
|
||||||
|
|
||||||
|
class DetachServerGroup(tables.BatchAction):
|
||||||
class DetachServerGroup(tables.BatchAction):
|
name = "detach"
|
||||||
name = "detach"
|
action_present = _("Detach")
|
||||||
action_present = _("Detach")
|
action_past = _("Detaching") # This action is asynchronous.
|
||||||
action_past = _("Detaching") # This action is asynchronous.
|
data_type_singular = _("Server Group")
|
||||||
data_type_singular = _("Server Group")
|
data_type_plural = _("Server Groups")
|
||||||
data_type_plural = _("Server Groups")
|
classes = ('btn-danger', 'btn-detach')
|
||||||
classes = ('btn-danger', 'btn-detach')
|
|
||||||
|
@staticmethod
|
||||||
@staticmethod
|
def action_present(count):
|
||||||
def action_present(count):
|
return ungettext_lazy(
|
||||||
return ungettext_lazy(
|
"Server Group",
|
||||||
"Server Group",
|
"Server Groups",
|
||||||
"Server Groups",
|
count
|
||||||
count
|
)
|
||||||
)
|
|
||||||
|
@staticmethod
|
||||||
@staticmethod
|
def action_past(count):
|
||||||
def action_past(count):
|
return ungettext_lazy(
|
||||||
return ungettext_lazy(
|
"Deleted Group",
|
||||||
"Deleted Group",
|
"Deleted Groups",
|
||||||
"Deleted Groups",
|
count
|
||||||
count
|
)
|
||||||
)
|
|
||||||
|
def action(self, request, obj_id):
|
||||||
def action(self, request, obj_id):
|
attachment = self.table.get_object_by_id(obj_id)
|
||||||
attachment = self.table.get_object_by_id(obj_id)
|
api.nova.instance_server_group_detach(
|
||||||
api.nova.instance_server_group_detach(
|
request,
|
||||||
request,
|
attachment.get('server_id', None),
|
||||||
attachment.get('server_id', None),
|
obj_id)
|
||||||
obj_id)
|
|
||||||
|
def get_success_url(self, request):
|
||||||
def get_success_url(self, request):
|
return reverse('horizon:project:server_groups:index')
|
||||||
return reverse('horizon:project:server_groups:index')
|
|
||||||
|
|
||||||
|
class AttachedInstanceColumn(tables.Column):
|
||||||
class AttachedInstanceColumn(tables.Column):
|
"""Customized column class
|
||||||
"""Customized column class
|
|
||||||
|
Customized column class that does complex processing on the attachments
|
||||||
Customized column class that does complex processing on the attachments
|
for a server group.
|
||||||
for a server group.
|
"""
|
||||||
"""
|
|
||||||
|
def get_raw_data(self, attachment):
|
||||||
def get_raw_data(self, attachment):
|
request = self.table.request
|
||||||
request = self.table.request
|
return safestring.mark_safe(get_attachment_name(request, attachment))
|
||||||
return safestring.mark_safe(get_attachment_name(request, attachment))
|
|
||||||
|
|
||||||
|
class AttachmentsTable(tables.DataTable):
|
||||||
class AttachmentsTable(tables.DataTable):
|
instance = AttachedInstanceColumn(get_member_name,
|
||||||
instance = AttachedInstanceColumn(get_member_name,
|
verbose_name=_("Instance"))
|
||||||
verbose_name=_("Instance"))
|
device = tables.Column("device",
|
||||||
device = tables.Column("device",
|
verbose_name=_("Device"))
|
||||||
verbose_name=_("Device"))
|
|
||||||
|
def get_object_id(self, obj):
|
||||||
def get_object_id(self, obj):
|
return obj['id']
|
||||||
return obj['id']
|
|
||||||
|
def get_object_display(self, attachment):
|
||||||
def get_object_display(self, attachment):
|
instance_name = get_attachment_name(self.request, attachment)
|
||||||
instance_name = get_attachment_name(self.request, attachment)
|
vals = {"dev": attachment['device'],
|
||||||
vals = {"dev": attachment['device'],
|
"instance_name": html.strip_tags(instance_name)}
|
||||||
"instance_name": html.strip_tags(instance_name)}
|
return _("%(dev)s on instance %(instance_name)s") % vals
|
||||||
return _("%(dev)s on instance %(instance_name)s") % vals
|
|
||||||
|
def get_object_by_id(self, obj_id):
|
||||||
def get_object_by_id(self, obj_id):
|
for obj in self.data:
|
||||||
for obj in self.data:
|
if self.get_object_id(obj) == obj_id:
|
||||||
if self.get_object_id(obj) == obj_id:
|
return obj
|
||||||
return obj
|
raise ValueError('No match found for the id "%s".' % obj_id)
|
||||||
raise ValueError('No match found for the id "%s".' % obj_id)
|
|
||||||
|
class Meta(object):
|
||||||
class Meta(object):
|
name = "attachments"
|
||||||
name = "attachments"
|
verbose_name = _("Attachments")
|
||||||
verbose_name = _("Attachments")
|
table_actions = (DetachServerGroup,)
|
||||||
table_actions = (DetachServerGroup,)
|
row_actions = (DetachServerGroup,)
|
||||||
row_actions = (DetachServerGroup,)
|
|
||||||
|
|
|
@ -1,53 +1,53 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
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 openstack_dashboard.api import nova
|
from openstack_dashboard.api import nova
|
||||||
|
|
||||||
from starlingx_dashboard.api import nova as stx_nova
|
from starlingx_dashboard.api import nova as stx_nova
|
||||||
|
|
||||||
|
|
||||||
class OverviewTab(tabs.Tab):
|
class OverviewTab(tabs.Tab):
|
||||||
name = _("Overview")
|
name = _("Overview")
|
||||||
slug = "overview"
|
slug = "overview"
|
||||||
template_name = ("project/server_groups/"
|
template_name = ("project/server_groups/"
|
||||||
"_detail_overview.html")
|
"_detail_overview.html")
|
||||||
|
|
||||||
def get_context_data(self, request):
|
def get_context_data(self, request):
|
||||||
server_group_id = self.tab_group.kwargs['server_group_id']
|
server_group_id = self.tab_group.kwargs['server_group_id']
|
||||||
try:
|
try:
|
||||||
server_group = stx_nova.server_group_get(request, server_group_id)
|
server_group = stx_nova.server_group_get(request, server_group_id)
|
||||||
server_group.members_display = []
|
server_group.members_display = []
|
||||||
for member in server_group.members:
|
for member in server_group.members:
|
||||||
server_group.members_display.append(
|
server_group.members_display.append(
|
||||||
dict(id=member, instance=nova.server_get(request, member)))
|
dict(id=member, instance=nova.server_get(request, member)))
|
||||||
except Exception:
|
except Exception:
|
||||||
redirect = reverse('horizon:project:server_groups:index')
|
redirect = reverse('horizon:project:server_groups:index')
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve server group details.'),
|
_('Unable to retrieve server group details.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
return {'server_group': server_group}
|
return {'server_group': server_group}
|
||||||
|
|
||||||
|
|
||||||
class ServerGroupDetailTabs(tabs.TabGroup):
|
class ServerGroupDetailTabs(tabs.TabGroup):
|
||||||
slug = "server_group_details"
|
slug = "server_group_details"
|
||||||
tabs = (OverviewTab,)
|
tabs = (OverviewTab,)
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from starlingx_dashboard.dashboards.project.server_groups import views
|
from starlingx_dashboard.dashboards.project.server_groups import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||||
url(r'^create/$', views.CreateView.as_view(), name='create'),
|
url(r'^create/$', views.CreateView.as_view(), name='create'),
|
||||||
url(r'^(?P<server_group_id>[^/]+)/attach/$',
|
url(r'^(?P<server_group_id>[^/]+)/attach/$',
|
||||||
views.EditAttachmentsView.as_view(),
|
views.EditAttachmentsView.as_view(),
|
||||||
name='attach'),
|
name='attach'),
|
||||||
url(r'^(?P<server_group_id>[^/]+)/$',
|
url(r'^(?P<server_group_id>[^/]+)/$',
|
||||||
views.DetailView.as_view(),
|
views.DetailView.as_view(),
|
||||||
name='detail'),
|
name='detail'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,148 +1,148 @@
|
||||||
# Copyright 2012 Nebula, Inc.
|
# Copyright 2012 Nebula, Inc.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
# a copy of the License at
|
# a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# 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-2017 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Views for managing server groups.
|
Views for managing server groups.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse_lazy # noqa
|
from django.core.urlresolvers import reverse_lazy # noqa
|
||||||
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 forms
|
from horizon import forms
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
from horizon import tabs
|
from horizon import tabs
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
from starlingx_dashboard import api as stx_api
|
from starlingx_dashboard import api as stx_api
|
||||||
from starlingx_dashboard.dashboards.project.server_groups \
|
from starlingx_dashboard.dashboards.project.server_groups \
|
||||||
import forms as project_forms
|
import forms as project_forms
|
||||||
from starlingx_dashboard.dashboards.project.server_groups \
|
from starlingx_dashboard.dashboards.project.server_groups \
|
||||||
import tables as project_tables
|
import tables as project_tables
|
||||||
from starlingx_dashboard.dashboards.project.server_groups \
|
from starlingx_dashboard.dashboards.project.server_groups \
|
||||||
import tabs as project_tabs
|
import tabs as project_tabs
|
||||||
|
|
||||||
|
|
||||||
# server groups don't currently support pagination
|
# server groups don't currently support pagination
|
||||||
class IndexView(tables.DataTableView):
|
class IndexView(tables.DataTableView):
|
||||||
table_class = project_tables.ServerGroupsTable
|
table_class = project_tables.ServerGroupsTable
|
||||||
template_name = 'project/server_groups/index.html'
|
template_name = 'project/server_groups/index.html'
|
||||||
page_title = _("Server Groups")
|
page_title = _("Server Groups")
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
try:
|
try:
|
||||||
server_groups = stx_api.nova.server_group_list(
|
server_groups = stx_api.nova.server_group_list(
|
||||||
self.request)
|
self.request)
|
||||||
except Exception:
|
except Exception:
|
||||||
server_groups = []
|
server_groups = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve server groups.'))
|
_('Unable to retrieve server groups.'))
|
||||||
return server_groups
|
return server_groups
|
||||||
|
|
||||||
|
|
||||||
class DetailView(tabs.TabView):
|
class DetailView(tabs.TabView):
|
||||||
tab_group_class = project_tabs.ServerGroupDetailTabs
|
tab_group_class = project_tabs.ServerGroupDetailTabs
|
||||||
template_name = 'project/server_groups/detail.html'
|
template_name = 'project/server_groups/detail.html'
|
||||||
page_title = 'Server Group Details'
|
page_title = 'Server Group Details'
|
||||||
|
|
||||||
|
|
||||||
class CreateView(forms.ModalFormView):
|
class CreateView(forms.ModalFormView):
|
||||||
form_class = project_forms.CreateForm
|
form_class = project_forms.CreateForm
|
||||||
template_name = 'project/server_groups/create.html'
|
template_name = 'project/server_groups/create.html'
|
||||||
success_url = reverse_lazy("horizon:project:server_groups:index")
|
success_url = reverse_lazy("horizon:project:server_groups:index")
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CreateView, self).get_context_data(**kwargs)
|
context = super(CreateView, self).get_context_data(**kwargs)
|
||||||
try:
|
try:
|
||||||
context['usages'] = quotas.tenant_limit_usages(self.request)
|
context['usages'] = quotas.tenant_limit_usages(self.request)
|
||||||
except Exception:
|
except Exception:
|
||||||
exceptions.handle(self.request)
|
exceptions.handle(self.request)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
|
class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
|
||||||
table_class = project_tables.AttachmentsTable
|
table_class = project_tables.AttachmentsTable
|
||||||
form_class = project_forms.AttachForm
|
form_class = project_forms.AttachForm
|
||||||
template_name = 'project/server_groups/attach.html'
|
template_name = 'project/server_groups/attach.html'
|
||||||
success_url = reverse_lazy("horizon:project:server_groups:index")
|
success_url = reverse_lazy("horizon:project:server_groups:index")
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
if not hasattr(self, "_object"):
|
if not hasattr(self, "_object"):
|
||||||
volume_id = self.kwargs['volume_id']
|
volume_id = self.kwargs['volume_id']
|
||||||
try:
|
try:
|
||||||
self._object = api.cinder.volume_get(self.request, volume_id)
|
self._object = api.cinder.volume_get(self.request, volume_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
self._object = None
|
self._object = None
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve volume information.'))
|
_('Unable to retrieve volume information.'))
|
||||||
return self._object
|
return self._object
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
try:
|
try:
|
||||||
volumes = self.get_object()
|
volumes = self.get_object()
|
||||||
attachments = [att for att in volumes.attachments if att]
|
attachments = [att for att in volumes.attachments if att]
|
||||||
except Exception:
|
except Exception:
|
||||||
attachments = []
|
attachments = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve volume information.'))
|
_('Unable to retrieve volume information.'))
|
||||||
return attachments
|
return attachments
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
try:
|
try:
|
||||||
instances, has_more = api.nova.server_list(self.request)
|
instances, has_more = api.nova.server_list(self.request)
|
||||||
except Exception:
|
except Exception:
|
||||||
instances = []
|
instances = []
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_("Unable to retrieve attachment information."))
|
_("Unable to retrieve attachment information."))
|
||||||
return {'volume': self.get_object(),
|
return {'volume': self.get_object(),
|
||||||
'instances': instances}
|
'instances': instances}
|
||||||
|
|
||||||
def get_form(self):
|
def get_form(self):
|
||||||
if not hasattr(self, "_form"):
|
if not hasattr(self, "_form"):
|
||||||
form_class = self.get_form_class()
|
form_class = self.get_form_class()
|
||||||
self._form = super(EditAttachmentsView, self).get_form(form_class)
|
self._form = super(EditAttachmentsView, self).get_form(form_class)
|
||||||
return self._form
|
return self._form
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(EditAttachmentsView, self).get_context_data(**kwargs)
|
context = super(EditAttachmentsView, self).get_context_data(**kwargs)
|
||||||
context['form'] = self.get_form()
|
context['form'] = self.get_form()
|
||||||
volume = self.get_object()
|
volume = self.get_object()
|
||||||
if volume and volume.status == 'available':
|
if volume and volume.status == 'available':
|
||||||
context['show_attach'] = True
|
context['show_attach'] = True
|
||||||
else:
|
else:
|
||||||
context['show_attach'] = False
|
context['show_attach'] = False
|
||||||
context['volume'] = volume
|
context['volume'] = volume
|
||||||
if self.request.is_ajax():
|
if self.request.is_ajax():
|
||||||
context['hide'] = True
|
context['hide'] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Table action handling
|
# Table action handling
|
||||||
handled = self.construct_tables()
|
handled = self.construct_tables()
|
||||||
if handled:
|
if handled:
|
||||||
return handled
|
return handled
|
||||||
return self.render_to_response(self.get_context_data(**kwargs))
|
return self.render_to_response(self.get_context_data(**kwargs))
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
return self.get(request, *args, **kwargs)
|
return self.get(request, *args, **kwargs)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# 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 = 'server_groups'
|
PANEL = 'server_groups'
|
||||||
# The slug of the dashboard the PANEL associated with. Required.
|
# The slug of the dashboard the PANEL associated with. Required.
|
||||||
PANEL_DASHBOARD = 'project'
|
PANEL_DASHBOARD = 'project'
|
||||||
# The slug of the panel group the PANEL is associated with.
|
# The slug of the panel group the PANEL is associated with.
|
||||||
PANEL_GROUP = 'compute'
|
PANEL_GROUP = 'compute'
|
||||||
# A list of applications to be added to INSTALLED_APPS.
|
# A list of applications to be added to INSTALLED_APPS.
|
||||||
|
|
||||||
# Python panel class of the PANEL to be added.
|
# Python panel class of the PANEL to be added.
|
||||||
ADD_PANEL = \
|
ADD_PANEL = \
|
||||||
'starlingx_dashboard.dashboards.project.server_groups.panel.ServerGroups'
|
'starlingx_dashboard.dashboards.project.server_groups.panel.ServerGroups'
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# 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 = 'server_groups'
|
PANEL = 'server_groups'
|
||||||
# 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.
|
||||||
PANEL_GROUP = 'compute'
|
PANEL_GROUP = 'compute'
|
||||||
|
|
||||||
# Python panel class of the PANEL to be added.
|
# Python panel class of the PANEL to be added.
|
||||||
ADD_PANEL = \
|
ADD_PANEL = \
|
||||||
'starlingx_dashboard.dashboards.admin.server_groups.panel.ServerGroups'
|
'starlingx_dashboard.dashboards.admin.server_groups.panel.ServerGroups'
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
from starlingx_dashboard.stx_horizon.tables.actions import FixedWithQueryFilter
|
from starlingx_dashboard.stx_horizon.tables.actions import FixedWithQueryFilter # noqa
|
||||||
from starlingx_dashboard.stx_horizon.tables.actions import LimitAction
|
from starlingx_dashboard.stx_horizon.tables.actions import LimitAction # noqa
|
||||||
|
|
|
@ -16,8 +16,10 @@ DEFAULT_TABLE_LIMITS = [10, 20, 50, 100, 500, 1000]
|
||||||
|
|
||||||
|
|
||||||
class FixedWithQueryFilter(FilterAction):
|
class FixedWithQueryFilter(FilterAction):
|
||||||
"""A FilterAction that visually renders like a combination
|
"""FilterAction
|
||||||
FixedFilterAction and a FilterAction of type "query.
|
|
||||||
|
A FilterAction that visually renders like a combination
|
||||||
|
FixedFilterAction and a FilterAction of type query.
|
||||||
|
|
||||||
Before extracting data from the filter, always ensure to first call
|
Before extracting data from the filter, always ensure to first call
|
||||||
the method updateFromRequestDataToSession(..) which will copy current
|
the method updateFromRequestDataToSession(..) which will copy current
|
||||||
|
@ -38,7 +40,9 @@ class FixedWithQueryFilter(FilterAction):
|
||||||
self.disabled_choices = []
|
self.disabled_choices = []
|
||||||
|
|
||||||
def _get_fieldFromGETorPOSTorSESSION(self, request, param_name):
|
def _get_fieldFromGETorPOSTorSESSION(self, request, param_name):
|
||||||
"""Utility method for getting 'named" data (param_name) from either
|
"""Utility method
|
||||||
|
|
||||||
|
Utility method for getting 'named" data (param_name) from either
|
||||||
GET/POST or Session .
|
GET/POST or Session .
|
||||||
IMPORTANT NOTE: Has the side-effect of storing the data into
|
IMPORTANT NOTE: Has the side-effect of storing the data into
|
||||||
the session
|
the session
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright (c) 2018 Intel Corporation
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
15
tox.ini
15
tox.ini
|
@ -33,15 +33,26 @@ commands =
|
||||||
|
|
||||||
ignore = E501,E129
|
ignore = E501,E129
|
||||||
|
|
||||||
|
[flake8]
|
||||||
|
# H102 Apache 2.0 license header not found
|
||||||
|
# B301 Python 3 does not include `.iter*` methods on dictionaries.
|
||||||
|
# B005 Using .strip() with multi-character strings is misleading the reader.
|
||||||
|
ignore = H102, B301, B005
|
||||||
|
# H106 Don’t put vim configuration in source files (off by default).
|
||||||
|
# H203 Use assertIs(Not)None to check for None (off by default).
|
||||||
|
# H904 Delay string interpolations at logging calls (off by default).
|
||||||
|
enable-extensions = H106,H203,H904
|
||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
usedevelop = False
|
usedevelop = False
|
||||||
skip_install = True
|
skip_install = True
|
||||||
deps =
|
deps =
|
||||||
pep8
|
hacking
|
||||||
|
flake8-bugbear
|
||||||
|
flake8<3.6.0
|
||||||
commands =
|
commands =
|
||||||
pep8
|
flake8
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
|
|
Loading…
Reference in New Issue