summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-06-28 19:54:41 +0000
committerGerrit Code Review <review@openstack.org>2022-06-28 19:54:41 +0000
commitf25ee1fc82bc4499b05384eb0f9e56ef95109bea (patch)
treeaa37f5aaa07b8cbef2be200fe9cc02fd733196ab
parent1ef45497117a3bd63f56427f1d82ae6d2f81f493 (diff)
parent15fe88b5af140709a433e94d737a7572aa755dc7 (diff)
downloadhorizon-f25ee1fc82bc4499b05384eb0f9e56ef95109bea.tar.gz
Merge "Add default_availability_zone for VM creation" into stable/wallaby
-rw-r--r--doc/source/configuration/settings.rst21
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js32
-rw-r--r--openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js50
-rw-r--r--openstack_dashboard/defaults.py1
-rw-r--r--releasenotes/notes/add_default_availability_zone-9c070832b2992958.yaml8
5 files changed, 107 insertions, 5 deletions
diff --git a/doc/source/configuration/settings.rst b/doc/source/configuration/settings.rst
index 935ba566e..166c76db8 100644
--- a/doc/source/configuration/settings.rst
+++ b/doc/source/configuration/settings.rst
@@ -2125,6 +2125,10 @@ LAUNCH_INSTANCE_DEFAULTS
Added the ``hide_create_volume`` option.
+.. versionchanged:: 19.1.0(Wallaby)
+
+ Added the ``default_availability_zone`` option.
+
Default:
.. code-block:: python
@@ -2138,6 +2142,7 @@ Default:
"disable_volume": False,
"disable_volume_snapshot": False,
"enable_scheduler_hints": True,
+ "default_availability_zone": "Any",
}
A dictionary of settings which can be used to provide the default values for
@@ -2224,6 +2229,22 @@ Default: ``True``
This setting specifies whether or not Scheduler Hints can be provided when
launching an instance.
+default_availability_zone
+#########################
+
+.. versionadded:: 19.1.0(Wallaby)
+
+Default: ``Any``
+
+This setting allows an administrator to specify a default availability zone
+for a new server creation. The valid value is ``Any`` or availability zone
+list. If ``Any`` is specified, the default availability zone is decided by
+the nova scheduler. If one of availability zones is specified, the specified
+availability zone is used as the default availability zone. If a value
+specified in this setting is not found in the availability zone list,
+the setting will be ignored and the behavior will be same as when ``Any``
+is specified.
+
LAUNCH_INSTANCE_LEGACY_ENABLED
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 147b0a120..dcec23d70 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
@@ -129,6 +129,7 @@
* cloud service properties, they should be READ-ONLY to all UI controllers
*/
+ default_availability_zone: 'Any',
availabilityZones: [],
flavors: [],
allowedBootSources: [],
@@ -250,6 +251,7 @@
});
promise = $q.all([
+ launchInstanceDefaults.then(setDefaultValues, noop),
novaAPI.getAvailabilityZones().then(onGetAvailabilityZones)
.finally(onGetAvailabilityZonesComplete),
novaAPI.getFlavors({
@@ -261,7 +263,6 @@
securityGroup.query().then(onGetSecurityGroups, noop),
serviceCatalog.ifTypeEnabled('network').then(getNetworks, noop),
launchInstanceDefaults.then(addImageSourcesIfEnabled, noop),
- launchInstanceDefaults.then(setDefaultValues, noop),
launchInstanceDefaults.then(addVolumeSourcesIfEnabled, noop)
]);
@@ -300,6 +301,9 @@
if ('hide_create_volume' in defaults) {
model.newInstanceSpec.hide_create_volume = defaults.hide_create_volume;
}
+ if ('default_availability_zone' in defaults) {
+ model.default_availability_zone = defaults.default_availability_zone;
+ }
}
/**
@@ -365,13 +369,33 @@
if (model.availabilityZones.length === 1) {
model.newInstanceSpec.availability_zone = model.availabilityZones[0].value;
} else if (model.availabilityZones.length > 1) {
- // There are 2 or more; allow ability for nova scheduler to pick,
- // and make that the default.
+ // There are 2 or more; allow ability for nova scheduler to pick any AZ
model.availabilityZones.unshift({
label: gettext("Any Availability Zone"),
value: ""
});
- model.newInstanceSpec.availability_zone = model.availabilityZones[0].value;
+ // if default_availability_zone is Any, pick the first one in the list
+ if (model.default_availability_zone === "Any") {
+ model.newInstanceSpec.availability_zone = model.availabilityZones[0].value;
+ } else {
+ var defaultZone = null;
+ for (var i = 0; i < model.availabilityZones.length; i++) {
+ if (model.availabilityZones[i].value === model.default_availability_zone) {
+ defaultZone = model.availabilityZones[i];
+ break;
+ }
+ }
+ if (defaultZone !== null) {
+ // if default_availability_zone is set, use that AZ by default.
+ model.newInstanceSpec.availability_zone = model.default_availability_zone;
+ // Add "(default)" suffix to the default AZ.
+ defaultZone.label = interpolate(gettext("%s (default)"), [defaultZone.value]);
+ } else {
+ // If the configured default AZ is not included in the AZ list (perhaps
+ // misconfiguration?), use the first one ("Any Availability Zone") by default.
+ model.newInstanceSpec.availability_zone = model.availabilityZones[0].value;
+ }
+ }
}
}
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 cc64988c9..e9d8d10f7 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
@@ -183,7 +183,8 @@
disable_image: false,
disable_instance_snapshot: false,
disable_volume: false,
- disable_volume_snapshot: false
+ disable_volume_snapshot: false,
+ default_availability_zone: 'Any'
},
DEFAULT_BOOT_SOURCE: 'image'
};
@@ -505,6 +506,37 @@
expect(model.newInstanceSpec.create_volume_default).toBe(false);
});
+ it('should default availability_zone to empty based on default', function() {
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toBe('');
+ });
+
+ it('should default availability_zone to empty based on setting', function() {
+ settings.LAUNCH_INSTANCE_DEFAULTS.default_availability_zone = 'Any';
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toBe('');
+ });
+
+ it('should default availability_zone based on setting', function() {
+ settings.LAUNCH_INSTANCE_DEFAULTS.default_availability_zone = 'zone-1';
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toEqual('zone-1');
+ });
+
+ it('should default AZ to empty if AZ configured is not found', function() {
+ settings.LAUNCH_INSTANCE_DEFAULTS.default_availability_zone = 'non-existing';
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toEqual('');
+ });
+
it('should default hide_create_volume to false if setting not provided', function() {
delete settings.LAUNCH_INSTANCE_DEFAULTS.hide_create_volume;
model.initialize(true);
@@ -628,6 +660,22 @@
expect(model.allowedBootSources).toContain(INSTANCE_SNAPSHOT);
});
+ it('should have proper availability_zone if specific setting is missing', function() {
+ delete settings.LAUNCH_INSTANCE_DEFAULTS.default_availability_zone;
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toBe('');
+ });
+
+ it('should have proper availability_zone if settings are missing', function() {
+ delete settings.LAUNCH_INSTANCE_DEFAULTS;
+ model.initialize(true);
+ scope.$apply();
+
+ expect(model.newInstanceSpec.availability_zone).toBe('');
+ });
+
it('should have proper allowedBootSources if settings are missing', function() {
delete settings.LAUNCH_INSTANCE_DEFAULTS;
model.initialize(true);
diff --git a/openstack_dashboard/defaults.py b/openstack_dashboard/defaults.py
index 45ce2d230..693395b98 100644
--- a/openstack_dashboard/defaults.py
+++ b/openstack_dashboard/defaults.py
@@ -265,6 +265,7 @@ LAUNCH_INSTANCE_DEFAULTS = {
'disable_volume': False,
'disable_volume_snapshot': False,
'enable_scheduler_hints': True,
+ 'default_availability_zone': 'Any',
}
# The absolute path to the directory where message files are collected.
diff --git a/releasenotes/notes/add_default_availability_zone-9c070832b2992958.yaml b/releasenotes/notes/add_default_availability_zone-9c070832b2992958.yaml
new file mode 100644
index 000000000..051a8f8d2
--- /dev/null
+++ b/releasenotes/notes/add_default_availability_zone-9c070832b2992958.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ When multiple availability zones are available, the default behavior is to
+ allow the scheduler to spawn a VM in any of them.
+ The new setting ``LAUNCH_INSTANCE_DEFAULTS.default_availability_zone``
+ allows an administrator to specify a default static availability zone
+ for new VM creation.