summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.zuul.d/base.yaml1
-rw-r--r--.zuul.d/tempest-and-integrated.yaml1
-rw-r--r--horizon/static/framework/widgets/metadata/tree/metadata-tree-item.controller.js8
-rw-r--r--horizon/static/framework/widgets/metadata/tree/tree.service.js2
-rw-r--r--openstack_dashboard/api/microversions.py1
-rw-r--r--openstack_dashboard/api/nova.py9
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/workflows.py4
-rw-r--r--openstack_dashboard/dashboards/project/floating_ips/tests.py2
-rw-r--r--openstack_dashboard/dashboards/project/instances/tests.py67
-rw-r--r--openstack_dashboard/dashboards/project/snapshots/views.py12
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js15
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js5
-rw-r--r--openstack_dashboard/locale/de/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po10
-rw-r--r--openstack_dashboard/locale/eo/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/es/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/fr/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/id/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/ja/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/ru/LC_MESSAGES/django.po9
-rw-r--r--openstack_dashboard/locale/zh_Hans/LC_MESSAGES/django.po7
-rw-r--r--openstack_dashboard/locale/zh_Hant/LC_MESSAGES/django.po7
-rw-r--r--openstack_dashboard/test/integration_tests/basewebobject.py7
-rw-r--r--openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py11
-rw-r--r--openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py10
-rw-r--r--openstack_dashboard/test/test_data/neutron_data.py20
-rw-r--r--openstack_dashboard/test/unit/api/test_neutron.py8
-rw-r--r--releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po8
-rw-r--r--tox.ini2
31 files changed, 160 insertions, 138 deletions
diff --git a/.zuul.d/base.yaml b/.zuul.d/base.yaml
index f6aa71360..06f8fd3a1 100644
--- a/.zuul.d/base.yaml
+++ b/.zuul.d/base.yaml
@@ -10,6 +10,7 @@
- job:
name: horizon-selenium-headless
parent: horizon-openstack-tox-base
+ nodeset: ubuntu-focal
pre-run: playbooks/horizon-selenium-headless/pre.yaml
vars:
tox_envlist: selenium-headless
diff --git a/.zuul.d/tempest-and-integrated.yaml b/.zuul.d/tempest-and-integrated.yaml
index df2e9b52a..c33578af0 100644
--- a/.zuul.d/tempest-and-integrated.yaml
+++ b/.zuul.d/tempest-and-integrated.yaml
@@ -1,6 +1,7 @@
- job:
name: horizon-integration-tests
parent: devstack
+ nodeset: openstack-single-node-focal
pre-run: playbooks/horizon-devstack-integration/pre.yaml
run: playbooks/horizon-devstack-integration/run.yaml
post-run: playbooks/horizon-devstack-integration/post.yaml
diff --git a/horizon/static/framework/widgets/metadata/tree/metadata-tree-item.controller.js b/horizon/static/framework/widgets/metadata/tree/metadata-tree-item.controller.js
index 27ab57d29..c4f8fb5af 100644
--- a/horizon/static/framework/widgets/metadata/tree/metadata-tree-item.controller.js
+++ b/horizon/static/framework/widgets/metadata/tree/metadata-tree-item.controller.js
@@ -16,6 +16,8 @@
(function () {
'use strict';
+ var READONLY_PROPERTIES = ['os_hash_algo', 'os_hash_value'];
+
angular
.module('horizon.framework.widgets.metadata.tree')
.controller('MetadataTreeItemController', MetadataTreeItemController);
@@ -33,6 +35,12 @@
ctrl.opened = false;
this.$onInit = function init() {
+ if ('item' in ctrl && 'leaf' in ctrl.item &&
+ READONLY_PROPERTIES.includes(ctrl.item.leaf.name)) {
+ ctrl.item.leaf.readonly = true;
+ ctrl.item.leaf.required = false;
+ }
+
if ('item' in ctrl && 'leaf' in ctrl.item && ctrl.item.leaf.type === 'array') {
ctrl.values = ctrl.item.leaf.items.enum.filter(filter).sort();
diff --git a/horizon/static/framework/widgets/metadata/tree/tree.service.js b/horizon/static/framework/widgets/metadata/tree/tree.service.js
index 1256985f5..47ba1a844 100644
--- a/horizon/static/framework/widgets/metadata/tree/tree.service.js
+++ b/horizon/static/framework/widgets/metadata/tree/tree.service.js
@@ -71,6 +71,8 @@
Property.prototype.setValue = function (value) {
if (value === null) {
this.value = this.type !== 'array' ? null : [];
+ // if the existing property is null, make the field not required
+ this.required = false;
return;
}
diff --git a/openstack_dashboard/api/microversions.py b/openstack_dashboard/api/microversions.py
index 9d33952ec..d31712ce8 100644
--- a/openstack_dashboard/api/microversions.py
+++ b/openstack_dashboard/api/microversions.py
@@ -37,6 +37,7 @@ MICROVERSION_FEATURES = {
"auto_allocated_network": ["2.37", "2.60"],
"key_types": ["2.2", "2.9"],
"key_type_list": ["2.9"],
+ "rescue_instance_volume_based": ["2.87", "2.93"],
},
"cinder": {
"groups": ["3.27", "3.43", "3.48", "3.58"],
diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py
index 981b1148d..03bdee1a9 100644
--- a/openstack_dashboard/api/nova.py
+++ b/openstack_dashboard/api/nova.py
@@ -665,9 +665,12 @@ def server_metadata_delete(request, instance_id, keys):
@profiler.trace
def server_rescue(request, instance_id, password=None, image=None):
- _nova.novaclient(request).servers.rescue(instance_id,
- password=password,
- image=image)
+ microversion = get_microversion(request, "rescue_instance_volume_based")
+ _nova.novaclient(request, version=microversion).servers.rescue(
+ instance_id,
+ password=password,
+ image=image
+ )
@profiler.trace
diff --git a/openstack_dashboard/dashboards/admin/flavors/workflows.py b/openstack_dashboard/dashboards/admin/flavors/workflows.py
index 074924eb8..3244ad992 100644
--- a/openstack_dashboard/dashboards/admin/flavors/workflows.py
+++ b/openstack_dashboard/dashboards/admin/flavors/workflows.py
@@ -30,7 +30,7 @@ class CreateFlavorInfoAction(workflows.Action):
_flavor_id_regex = (r'^[a-zA-Z0-9. _-]+$')
_flavor_id_help_text = _("flavor id can only contain alphanumeric "
"characters, underscores, periods, hyphens, "
- "spaces.")
+ "spaces. Use 'auto' to automatically generate id")
name = forms.CharField(
label=_("Name"),
max_length=255)
@@ -93,7 +93,7 @@ class CreateFlavorInfoAction(workflows.Action):
error_msg = _('The name "%s" is already used by '
'another flavor.') % name
self._errors['name'] = self.error_class([error_msg])
- if flavor.id == flavor_id:
+ if (flavor.id != 'auto') and (flavor.id == flavor_id):
error_msg = _('The ID "%s" is already used by '
'another flavor.') % flavor_id
self._errors['flavor_id'] = self.error_class([error_msg])
diff --git a/openstack_dashboard/dashboards/project/floating_ips/tests.py b/openstack_dashboard/dashboards/project/floating_ips/tests.py
index eca92dcd8..8c94c1f1f 100644
--- a/openstack_dashboard/dashboards/project/floating_ips/tests.py
+++ b/openstack_dashboard/dashboards/project/floating_ips/tests.py
@@ -90,7 +90,7 @@ class FloatingIpViewTests(test.TestCase):
for p in self._get_compute_ports():
for ip in p.fixed_ips:
targets.append(api.neutron.FloatingIpTarget(
- p, ip['ip_address'], server_dict[p.device_id]))
+ p, ip['ip_address'], server_dict.get(p.device_id)))
return targets
@staticmethod
diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py
index 93151a410..70d32bc4b 100644
--- a/openstack_dashboard/dashboards/project/instances/tests.py
+++ b/openstack_dashboard/dashboards/project/instances/tests.py
@@ -3054,11 +3054,14 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
'port_list_with_trunk_types')})
def test_interface_attach_get(self):
server = self.servers.first()
- self.mock_network_list_for_tenant.side_effect = [
- self.networks.list()[:1],
- [],
- ]
- self.mock_port_list_with_trunk_types.return_value = self.ports.list()
+ tenant_networks = [net for net in self.networks.list()
+ if not net['router:external']]
+ net1 = tenant_networks[0]
+ self.mock_network_list_for_tenant.return_value = tenant_networks
+ ports = self.ports.list()
+ # Pick up the first unbound port for check
+ unbound_port = [p for p in ports if not p.device_owner][0]
+ self.mock_port_list_with_trunk_types.return_value = ports
url = reverse('horizon:project:instances:attach_interface',
args=[server.id])
@@ -3066,6 +3069,13 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
self.assertTemplateUsed(res,
'project/instances/attach_interface.html')
+ expected_label = (
+ '%(port_name)s (%(ip_address)s) - %(net_name)s'
+ % {'port_name': unbound_port.name_or_id,
+ 'ip_address': unbound_port.fixed_ips[0]['ip_address'],
+ 'net_name': net1.name_or_id}
+ )
+ self.assertContains(res, expected_label)
self.mock_network_list_for_tenant.assert_has_calls([
mock.call(helpers.IsHttpRequest(), self.tenant.id),
mock.call(helpers.IsHttpRequest(), self.tenant.id),
@@ -3077,21 +3087,31 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
@helpers.create_mocks({api.neutron: ('network_list_for_tenant',
'port_list_with_trunk_types'),
api.nova: ('interface_attach',)})
- def test_interface_attach_post(self):
+ def _test_interface_attach_post(self, by_port=False):
fixed_ip = '10.0.0.10'
server = self.servers.first()
network = self.networks.first()
- self.mock_network_list_for_tenant.side_effect = [
- [network],
- [],
- ]
- self.mock_port_list_with_trunk_types.return_value = self.ports.list()
+ ports = self.ports.list()
+ # Pick up the first unbound port for check
+ unbound_port = [p for p in ports if not p.device_owner][0]
+
+ self.mock_network_list_for_tenant.return_value = [network]
+ self.mock_port_list_with_trunk_types.return_value = ports
self.mock_interface_attach.return_value = None
- form_data = {'instance_id': server.id,
- 'network': network.id,
- 'specification_method': 'network',
- 'fixed_ip': fixed_ip}
+ if by_port:
+ form_data = {
+ 'instance_id': server.id,
+ 'specification_method': 'port',
+ 'port': unbound_port.id,
+ }
+ else:
+ form_data = {
+ 'instance_id': server.id,
+ 'specification_method': 'network',
+ 'network': network.id,
+ 'fixed_ip': fixed_ip,
+ }
url = reverse('horizon:project:instances:attach_interface',
args=[server.id])
@@ -3107,9 +3127,20 @@ class ConsoleManagerTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
self.assertEqual(2, self.mock_network_list_for_tenant.call_count)
self.mock_port_list_with_trunk_types.assert_called_once_with(
helpers.IsHttpRequest(), tenant_id=self.tenant.id)
- self.mock_interface_attach.assert_called_once_with(
- helpers.IsHttpRequest(), server.id,
- net_id=network.id, fixed_ip=fixed_ip, port_id=None)
+ if by_port:
+ self.mock_interface_attach.assert_called_once_with(
+ helpers.IsHttpRequest(), server.id,
+ net_id=None, fixed_ip=None, port_id=unbound_port.id)
+ else:
+ self.mock_interface_attach.assert_called_once_with(
+ helpers.IsHttpRequest(), server.id,
+ net_id=network.id, fixed_ip=fixed_ip, port_id=None)
+
+ def test_interface_attach_post_by_network(self):
+ self._test_interface_attach_post()
+
+ def test_interface_attach_post_by_port(self):
+ self._test_interface_attach_post(by_port=True)
@helpers.create_mocks({api.cinder: ('volume_list',)})
def test_volume_attach_get(self):
diff --git a/openstack_dashboard/dashboards/project/snapshots/views.py b/openstack_dashboard/dashboards/project/snapshots/views.py
index 7efc4a892..faf727926 100644
--- a/openstack_dashboard/dashboards/project/snapshots/views.py
+++ b/openstack_dashboard/dashboards/project/snapshots/views.py
@@ -12,7 +12,6 @@
from django.urls import reverse
from django.urls import reverse_lazy
-from django.utils.http import urlencode
from django.utils.translation import gettext_lazy as _
from horizon import exceptions
@@ -104,11 +103,8 @@ class UpdateView(forms.ModalFormView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['snapshot'] = self.get_object()
- success_url = self.request.GET.get('success_url', "")
args = (self.kwargs['snapshot_id'],)
- params = urlencode({"success_url": success_url})
- context['submit_url'] = "?".join([reverse(self.submit_url, args=args),
- params])
+ context['submit_url'] = reverse(self.submit_url, args=args)
return context
def get_initial(self):
@@ -117,12 +113,6 @@ class UpdateView(forms.ModalFormView):
'name': snapshot.name,
'description': snapshot.description}
- def get_success_url(self):
- success_url = self.request.GET.get(
- "success_url",
- reverse_lazy("horizon:project:snapshots:index"))
- return success_url
-
class DetailView(tabs.TabView):
tab_group_class = vol_snapshot_tabs.SnapshotDetailTabs
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js
index 26086bc14..c38d75bc4 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js
@@ -676,14 +676,17 @@
}
function getImageType(image) {
- if (image === null || !angular.isDefined(image.properties) ||
- !(angular.isDefined(image.properties.image_type) ||
- angular.isDefined(image.properties.block_device_mapping))) {
+ if (image === null || !image.properties) {
return 'image';
}
- return image.properties.image_type ||
- angular.fromJson(image.properties.block_device_mapping)[0].source_type ||
- 'image';
+ if (image.properties.image_type) {
+ return image.properties.image_type;
+ }
+ var bdm = angular.fromJson(image.properties.block_device_mapping || "[]");
+ if (bdm[0] && bdm[0].source_type) {
+ return bdm[0].source_type;
+ }
+ return 'image';
}
function isValidImage(image) {
diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
index fa15af910..27a580698 100644
--- a/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
+++ b/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
@@ -151,6 +151,8 @@
{id: '4', container_format: 'raw', properties: {}, name: 'raw_image'},
{id: '5', container_format: 'ami', properties: {image_type: 'image'}},
{id: '6', container_format: 'raw', properties: {image_type: 'image'}},
+ {id: '11', container_format: 'raw', properties: {image_type: ''}},
+ {id: '12', container_format: 'raw', properties: {block_device_mapping: '[]'}},
// The following images are considered as "snapshot" sources.
{id: '7', container_format: 'ami',
properties: {block_device_mapping: '[{"source_type": "snapshot"}]'}},
@@ -393,6 +395,9 @@
name_or_id: 'raw_image'},
{id: '5', container_format: 'ami', properties: {image_type: 'image'}, name_or_id: '5'},
{id: '6', container_format: 'raw', properties: {image_type: 'image'}, name_or_id: '6'},
+ {id: '11', container_format: 'raw', properties: {image_type: ''}, name_or_id: '11'},
+ {id: '12', container_format: 'raw', properties: {block_device_mapping: '[]'},
+ name_or_id: '12'},
{id: '10', container_format: 'raw', properties: {image_type: 'image'}, name_or_id: '10',
visibility: 'community'},
];
diff --git a/openstack_dashboard/locale/de/LC_MESSAGES/django.po b/openstack_dashboard/locale/de/LC_MESSAGES/django.po
index 10d7f5473..44d08e212 100644
--- a/openstack_dashboard/locale/de/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/de/LC_MESSAGES/django.po
@@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8895,13 +8895,6 @@ msgstr "z.B. Ja / Nein"
msgid "e.g. Yes/No"
msgstr "z.B. Ja/Nein"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"Varianten ID darf nur alphanumerische Zeichen, Unterstriche, Punkte, "
-"Bindestriche und Leerzeichen enthalten."
-
msgid "front-end"
msgstr "Frontend"
diff --git a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po b/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po
index a4b427f96..eed773fa6 100644
--- a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po
@@ -13,11 +13,11 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-09-21 16:22+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2022-09-24 01:11+0000\n"
+"PO-Revision-Date: 2022-11-04 10:35+0000\n"
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
"Language-Team: English (United Kingdom)\n"
"Language: en_GB\n"
@@ -8801,10 +8801,10 @@ msgstr "e.g. Yes/No"
msgid ""
"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
+"hyphens, spaces. Use 'auto' to automatically generate id"
msgstr ""
-"flavour id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
+"flavour id can only contain alphanumeric characters, underscores, fullstops, "
+"hyphens, spaces. Use 'auto' to automatically generate id"
msgid "front-end"
msgstr "front-end"
diff --git a/openstack_dashboard/locale/eo/LC_MESSAGES/django.po b/openstack_dashboard/locale/eo/LC_MESSAGES/django.po
index fa44f0cd6..97b576a77 100644
--- a/openstack_dashboard/locale/eo/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/eo/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-09-30 06:37+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8803,13 +8803,6 @@ msgstr "ekz. Jes / Ne"
msgid "e.g. Yes/No"
msgstr "ekz. Jes/Ne"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-" speco id nur enhavus literciferajn signojn, substrekojn, punktojn,"
-"dividstrekojn, blankspacojn."
-
msgid "front-end"
msgstr "fasada"
diff --git a/openstack_dashboard/locale/es/LC_MESSAGES/django.po b/openstack_dashboard/locale/es/LC_MESSAGES/django.po
index 2465a68c0..0dde555aa 100644
--- a/openstack_dashboard/locale/es/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/es/LC_MESSAGES/django.po
@@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8974,13 +8974,6 @@ msgstr "e.j Si/ No"
msgid "e.g. Yes/No"
msgstr "p. ej. Sí/No"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"El id del sabor solo puede contener caracteres alfanuméricos, guiones "
-"normales y bajos, puntos y espacios."
-
msgid "front-end"
msgstr "front-end"
diff --git a/openstack_dashboard/locale/fr/LC_MESSAGES/django.po b/openstack_dashboard/locale/fr/LC_MESSAGES/django.po
index ebf5ca5fe..d23309395 100644
--- a/openstack_dashboard/locale/fr/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/fr/LC_MESSAGES/django.po
@@ -26,7 +26,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8546,13 +8546,6 @@ msgstr "ex : Oui / Non"
msgid "e.g. Yes/No"
msgstr "ex : Oui/Non"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"Un id de gabarit ne peut comporter que des caractères alphanumériques, des "
-"soulignés, des points, des traits d'union ou des espaces."
-
msgid "front-end"
msgstr "front-end"
diff --git a/openstack_dashboard/locale/id/LC_MESSAGES/django.po b/openstack_dashboard/locale/id/LC_MESSAGES/django.po
index bbb4b4cd3..39fd03f21 100644
--- a/openstack_dashboard/locale/id/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/id/LC_MESSAGES/django.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8636,13 +8636,6 @@ msgstr "e.g. Yes / No"
msgid "e.g. Yes/No"
msgstr "misalnya Ya Tidak"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"flavor id hanya dapat berisi karakter alfanumerik, garis bawah, titik, tanda "
-"hubung, spasi."
-
msgid "front-end"
msgstr "front-end"
diff --git a/openstack_dashboard/locale/ja/LC_MESSAGES/django.po b/openstack_dashboard/locale/ja/LC_MESSAGES/django.po
index 494a7b4e5..42ab9bef8 100644
--- a/openstack_dashboard/locale/ja/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/ja/LC_MESSAGES/django.po
@@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-10-13 05:54+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8759,13 +8759,6 @@ msgstr "例: Yes / No"
msgid "e.g. Yes/No"
msgstr "例: Yes/No"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"フレーバーの ID に使用できるのは、英数字、アンダースコアー、ピリオド、ハイフ"
-"ン、空白文字のみです。"
-
msgid "front-end"
msgstr "フロントエンド"
diff --git a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po b/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po
index e3e04e99e..706a335c5 100644
--- a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po
@@ -30,7 +30,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8487,13 +8487,6 @@ msgstr "예시: Yes / No"
msgid "e.g. Yes/No"
msgstr "예: Yes/No"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"flavor id는 영숫자 문자, 밑줄, 마침표, 콜론, 하이픈, 스페이스만 포함할 수 있"
-"습니다."
-
msgid "front-end"
msgstr "프론트-엔드"
diff --git a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po b/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po
index f7f0d0574..ac89bd3a3 100644
--- a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po
@@ -17,7 +17,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8245,13 +8245,6 @@ msgstr "i.e. Sim / Não"
msgid "e.g. Yes/No"
msgstr "i.e. Sim/Não"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"Identificador do sabor pode conter somente caracteres alfanuméricos, "
-"sublinhados, pontos, hifens e espaços."
-
msgid "front-end"
msgstr "front-end"
diff --git a/openstack_dashboard/locale/ru/LC_MESSAGES/django.po b/openstack_dashboard/locale/ru/LC_MESSAGES/django.po
index 2a8916028..b46174599 100644
--- a/openstack_dashboard/locale/ru/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/ru/LC_MESSAGES/django.po
@@ -41,7 +41,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-10-13 05:54+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8998,13 +8998,6 @@ msgstr "т.е. Да/Нет"
msgid "e.g. Yes/No"
msgstr "т.е. Да/Нет"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr ""
-"Имя типа инстанса может сождержать только алфавитно-цифровые символы, "
-"символы подчеркивания, точки, дефисы и пробелы."
-
msgid "front-end"
msgstr "фронтэнд"
diff --git a/openstack_dashboard/locale/zh_Hans/LC_MESSAGES/django.po b/openstack_dashboard/locale/zh_Hans/LC_MESSAGES/django.po
index ce4484d82..b6ee05bef 100644
--- a/openstack_dashboard/locale/zh_Hans/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/zh_Hans/LC_MESSAGES/django.po
@@ -33,7 +33,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -8188,11 +8188,6 @@ msgstr "例如,Yes / No"
msgid "e.g. Yes/No"
msgstr "例如,是/否"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr "实例类型 id 只能包含字母数字字符、下划线、句点、连字符和空格。"
-
msgid "front-end"
msgstr "前端"
diff --git a/openstack_dashboard/locale/zh_Hant/LC_MESSAGES/django.po b/openstack_dashboard/locale/zh_Hant/LC_MESSAGES/django.po
index 944f6053d..444b28889 100644
--- a/openstack_dashboard/locale/zh_Hant/LC_MESSAGES/django.po
+++ b/openstack_dashboard/locale/zh_Hant/LC_MESSAGES/django.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n"
-"POT-Creation-Date: 2022-06-21 10:46+0000\n"
+"POT-Creation-Date: 2022-11-04 11:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -7796,11 +7796,6 @@ msgstr "例如:Yes/No"
msgid "e.g. Yes/No"
msgstr "例如:Yes/No"
-msgid ""
-"flavor id can only contain alphanumeric characters, underscores, periods, "
-"hyphens, spaces."
-msgstr "樣板 ID 名稱只能包含英數字元、底線、句點、連字號及空白鍵。"
-
msgid "front-end"
msgstr "前端"
diff --git a/openstack_dashboard/test/integration_tests/basewebobject.py b/openstack_dashboard/test/integration_tests/basewebobject.py
index aae87e910..f4207b0ce 100644
--- a/openstack_dashboard/test/integration_tests/basewebobject.py
+++ b/openstack_dashboard/test/integration_tests/basewebobject.py
@@ -152,6 +152,13 @@ class BaseWebObject(unittest.TestCase):
# it will raise the NoSuchElementException exception.
pass
+ def wait_until_element_is_visible(self, locator):
+ with self.waits_disabled():
+ try:
+ self._wait_till_element_visible(locator)
+ except Exceptions.NoSuchElementException:
+ pass
+
def wait_till_spinner_disappears(self):
def getter():
return self.driver.find_element(*self._spinner_locator)
diff --git a/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py b/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
index 117c64b5c..0c61bfcea 100644
--- a/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
+++ b/openstack_dashboard/test/integration_tests/pages/project/compute/imagespage.py
@@ -117,6 +117,14 @@ class ImagesPage(basepage.BaseNavigationPage):
'hz-magic-search-bar span.fa-search')
_search_option_locator = (by.By.CSS_SELECTOR,
'magic-search.form-control span.search-entry')
+ _search_name_locator_filled = (
+ by.By.XPATH,
+ "//*[@id='imageForm-name'][contains(@class,'ng-not-empty')]"
+ )
+ _search_checkbox_loaded = (
+ by.By.CSS_SELECTOR,
+ "td .themable-checkbox [type='checkbox'] + label[for*='Zactive']"
+ )
def __init__(self, driver, conf):
super().__init__(driver, conf)
@@ -134,6 +142,8 @@ class ImagesPage(basepage.BaseNavigationPage):
return self._get_element(*self._default_form_locator)
def _get_row_with_image_name(self, name):
+ self.wait_until_element_is_visible(self._search_checkbox_loaded)
+
return self.images_table.get_row(IMAGES_TABLE_NAME_COLUMN, name)
def create_image(self, name, description=None,
@@ -178,6 +188,7 @@ class ImagesPage(basepage.BaseNavigationPage):
visibility=None, protected=None):
row = self._get_row_with_image_name(name)
confirm_edit_images_form = self.images_table.edit_image(row)
+ self.wait_until_element_is_visible(self._search_name_locator_filled)
if new_name is not None:
confirm_edit_images_form.name.text = new_name
diff --git a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
index 2293abec1..236d9465d 100644
--- a/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
+++ b/openstack_dashboard/test/integration_tests/pages/project/compute/instancespage.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import netaddr
+from selenium.common import exceptions
from selenium.webdriver.common import by
from openstack_dashboard.test.integration_tests.pages import basepage
@@ -64,6 +65,11 @@ class InstancesPage(basepage.BaseNavigationPage):
FLAVOR_STEP_INDEX = 2
NETWORKS_STEP_INDEX = 3
+ _search_state_active = (
+ by.By.XPATH,
+ "//*[contains(@class,'normal_column')][contains(text(),'Active')]"
+ )
+
def __init__(self, driver, conf):
super().__init__(driver, conf)
self._page_title = "Instances"
@@ -155,6 +161,10 @@ class InstancesPage(basepage.BaseNavigationPage):
row = self._get_row_with_instance_name(name)
return row and row.cells[self.INSTANCES_TABLE_STATUS_COLUMN]
+ try:
+ self.wait_until_element_is_visible(self._search_state_active)
+ except exceptions.TimeoutException:
+ return False
status = self.instances_table.wait_cell_status(cell_getter,
('Active', 'Error'))
return status == 'Active'
diff --git a/openstack_dashboard/test/test_data/neutron_data.py b/openstack_dashboard/test/test_data/neutron_data.py
index 7ac5eafb1..78bd93df3 100644
--- a/openstack_dashboard/test/test_data/neutron_data.py
+++ b/openstack_dashboard/test/test_data/neutron_data.py
@@ -222,6 +222,26 @@ def data(TEST):
TEST.api_ports.add(port_dict)
TEST.ports.add(neutron.Port(port_dict))
+ # unbound port on 1st network
+ port_dict = {
+ 'admin_state_up': True,
+ 'device_id': '',
+ 'device_owner': '',
+ 'fixed_ips': [{'ip_address': '10.0.0.5',
+ 'subnet_id': subnet_dict['id']}],
+ 'id': 'a5aa0d62-cd5f-4e7d-b022-4ff63f981bcd',
+ 'mac_address': 'fa:16:3e:ce:e0:f8',
+ 'name': '',
+ 'network_id': network_dict['id'],
+ 'status': 'DOWN',
+ 'tenant_id': network_dict['tenant_id'],
+ 'binding:vnic_type': 'normal',
+ 'binding:host_id': '',
+ 'security_groups': [],
+ }
+ TEST.api_ports.add(port_dict)
+ TEST.ports.add(neutron.Port(port_dict))
+
# 2nd network.
network_dict = {'admin_state_up': True,
'id': '72c3ab6c-c80f-4341-9dc5-210fa31ac6c2',
diff --git a/openstack_dashboard/test/unit/api/test_neutron.py b/openstack_dashboard/test/unit/api/test_neutron.py
index 5eb6bbd7b..19bde8df1 100644
--- a/openstack_dashboard/test/unit/api/test_neutron.py
+++ b/openstack_dashboard/test/unit/api/test_neutron.py
@@ -2488,9 +2488,11 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
return '%(id)s_%(addr)s' % param
def _get_target_name(self, port, ip=None):
- param = {'svrid': port['device_id'],
- 'addr': ip or port['fixed_ips'][0]['ip_address']}
- return 'server_%(svrid)s: %(addr)s' % param
+ ip_address = ip or port['fixed_ips'][0]['ip_address']
+ if port['device_id']:
+ return 'server_%s: %s' % (port['device_id'], ip_address)
+ else:
+ return ip_address
@override_settings(
OPENSTACK_NEUTRON_NETWORK={
diff --git a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
index a28cd44b1..0dd0d778a 100644
--- a/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
+++ b/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po
@@ -9,11 +9,11 @@ msgid ""
msgstr ""
"Project-Id-Version: horizon\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-09-21 16:17+0000\n"
+"POT-Creation-Date: 2022-11-04 11:39+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"PO-Revision-Date: 2022-09-24 01:10+0000\n"
+"PO-Revision-Date: 2022-11-04 10:35+0000\n"
"Last-Translator: Andi Chandler <andi@gowling.com>\n"
"Language-Team: English (United Kingdom)\n"
"Language: en_GB\n"
@@ -168,8 +168,8 @@ msgstr "18.3.0"
msgid "18.3.3"
msgstr "18.3.3"
-msgid "18.3.5-4"
-msgstr "18.3.5-4"
+msgid "18.3.5-6"
+msgstr "18.3.5-6"
msgid "18.5.0"
msgstr "18.5.0"
diff --git a/tox.ini b/tox.ini
index 8a4ebfab8..3861801a9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -106,7 +106,7 @@ setenv =
SELENIUM_HEADLESS=False
commands =
oslo-config-generator --namespace openstack_dashboard_integration_tests
- pytest --ds=openstack_dashboard.test.settings -v --junitxml="{toxinidir}/test_reports/integration_test_results.xml" --html="{toxinidir}/test_reports/integration_test_results.html" --self-contained-html {posargs:{toxinidir}/openstack_dashboard/test/integration_tests}
+ pytest --ds=openstack_dashboard.test.settings -v -x --junitxml="{toxinidir}/test_reports/integration_test_results.xml" --html="{toxinidir}/test_reports/integration_test_results.html" --self-contained-html {posargs:{toxinidir}/openstack_dashboard/test/integration_tests}
[testenv:npm]
passenv =