Browse Source

Add default_availability_zone for VM creation

Add the LAUNCH_INSTANCE_DEFAULTS.default_availability_zone settings in
VM creation dashboard in order to let administrator select a default
availability zone instead of a random one when many are available.

Co-Authored-By: Akihiro Motoki <amotoki@gmail.com>
Change-Id: I297ff7f3c8e725c24c7f7687786c784f61f5d4e2
changes/52/750752/39
David Hill 11 months ago
committed by Akihiro Motoki
parent
commit
fc8603a499
  1. 21
      doc/source/configuration/settings.rst
  2. 32
      openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js
  3. 50
      openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.spec.js
  4. 1
      openstack_dashboard/defaults.py
  5. 8
      releasenotes/notes/add_default_availability_zone-9c070832b2992958.yaml

21
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

32
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;
}
}
}
}

50
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);

1
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.

8
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.
Loading…
Cancel
Save