Extend settings with OPENSTACK_SERVER_DEFAULT_USER_DATA
The new setting should allow an administrator to specify default user_data for new VMs. The default user_data can be a string template that accepts request object which has info about the user, so the default user_data can be personalized. Change-Id: I86ac21bf82c1667135abd4f20fb4514da0899450
This commit is contained in:
parent
0a77f42156
commit
3a2e82ab75
@ -2224,7 +2224,7 @@ hide_create_volume
|
||||
|
||||
Default: ``False``
|
||||
|
||||
This setting allow your to hide the "Create New Volume" option and rely on the
|
||||
This setting allows you to hide the "Create New Volume" option and rely on the
|
||||
default value you select with ``create_volume`` to be the most suitable for your
|
||||
users.
|
||||
|
||||
@ -2314,6 +2314,17 @@ 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.
|
||||
|
||||
OPENSTACK_SERVER_DEFAULT_USER_DATA
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 22.3.0(Zed)
|
||||
|
||||
Default: ``""``
|
||||
|
||||
An administrator can specify a default user data (e.g. comments or instructions
|
||||
for cloudinit) via this settings. It can be a string or template string that
|
||||
accepts a request object.
|
||||
|
||||
OPENSTACK_ENABLE_PASSWORD_RETRIEVE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
*
|
||||
* @param {object} title
|
||||
* @param {object} model
|
||||
* @param {object} modelDefaultValue
|
||||
* @param {object} maxBytes
|
||||
* @param {object} key
|
||||
* @param {object} required
|
||||
@ -49,6 +50,7 @@
|
||||
scope: {
|
||||
title: '@',
|
||||
model: '=',
|
||||
modelDefaultValue: '=',
|
||||
maxBytes: '@',
|
||||
key: '@',
|
||||
required: '=',
|
||||
@ -141,6 +143,12 @@
|
||||
textarea.focus();
|
||||
}
|
||||
|
||||
$scope.$watch('modelDefaultValue', function(newValue, oldValue) {
|
||||
if (newValue !== undefined && oldValue !== newValue) {
|
||||
updateTextArea(newValue);
|
||||
}
|
||||
});
|
||||
|
||||
/* The length property for string shows only number of character.
|
||||
* If text includes multibyte string, it doesn't mean number of bytes.
|
||||
* So to count bytes, convert to Blob object and get its size.
|
||||
|
@ -39,8 +39,9 @@
|
||||
$compile = $injector.get('$compile');
|
||||
key = 'elementKey';
|
||||
element = $compile(
|
||||
'<load-edit title="{}" model="{}" max-bytes="{}" key="' + key + '" ' +
|
||||
'required="true" rows="8"></load-edit>'
|
||||
'<load-edit title="{}" model="{}" model-default-value="{}"' +
|
||||
'max-bytes="{}" key="' + key + '" ' + 'required="true" rows="8">' +
|
||||
'</load-edit>'
|
||||
)($scope);
|
||||
$scope.$apply();
|
||||
}));
|
||||
@ -75,6 +76,15 @@
|
||||
|
||||
expect(element.isolateScope().model).toBe('user input');
|
||||
});
|
||||
|
||||
it('should update text area with default user data', function () {
|
||||
element.isolateScope().modelDefaultValue = 'default user data';
|
||||
$scope.$apply();
|
||||
textarea.trigger('input');
|
||||
$scope.$apply();
|
||||
|
||||
expect(element.isolateScope().model).toBe('default user data');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onFileLoadListener', function() {
|
||||
|
@ -17,6 +17,7 @@ from datetime import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import JsonResponse
|
||||
import django.template as django_template
|
||||
from django.views import generic
|
||||
import pytz
|
||||
|
||||
@ -59,6 +60,7 @@ class Settings(generic.View):
|
||||
in settings_allowed if k not in self.SPECIALS}
|
||||
plain_settings.update(self.SPECIALS)
|
||||
plain_settings.update(self.disk_formats(request))
|
||||
plain_settings.update(self.default_user_data(request))
|
||||
return plain_settings
|
||||
|
||||
def disk_formats(self, request):
|
||||
@ -70,6 +72,18 @@ class Settings(generic.View):
|
||||
for (value, name) in api.glance.get_image_formats(request)
|
||||
]}
|
||||
|
||||
def default_user_data(self, request):
|
||||
template_code = settings.OPENSTACK_SERVER_DEFAULT_USER_DATA
|
||||
if template_code:
|
||||
engine = django_template.engine.Engine.get_default()
|
||||
template = engine.from_string(template_code)
|
||||
default_user_data = template.render(
|
||||
django_template.Context(dict(request=request))
|
||||
)
|
||||
else:
|
||||
default_user_data = ""
|
||||
return {"OPENSTACK_SERVER_DEFAULT_USER_DATA": default_user_data}
|
||||
|
||||
|
||||
@urls.register
|
||||
class Timezones(generic.View):
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
<load-edit title="{$ ctrl.title $}"
|
||||
model="model.newInstanceSpec.user_data"
|
||||
model-default-value="model.newInstanceSpec.default_user_data"
|
||||
max-bytes="{$ ctrl.MAX_SCRIPT_SIZE $}"
|
||||
key="user-data"
|
||||
rows=8>
|
||||
|
@ -182,6 +182,7 @@
|
||||
description: null,
|
||||
// REQUIRED Server Key. Null allowed.
|
||||
user_data: '',
|
||||
default_user_data: '',
|
||||
disk_config: 'AUTO',
|
||||
// REQUIRED
|
||||
flavor: null,
|
||||
@ -249,6 +250,10 @@
|
||||
function (response) {
|
||||
model.defaultBootSource = response;
|
||||
});
|
||||
settings.getSetting("OPENSTACK_SERVER_DEFAULT_USER_DATA").then(
|
||||
function (response) {
|
||||
model.newInstanceSpec.default_user_data = response.OPENSTACK_SERVER_DEFAULT_USER_DATA;
|
||||
});
|
||||
|
||||
promise = $q.all([
|
||||
launchInstanceDefaults.then(setDefaultValues, noop),
|
||||
|
@ -186,7 +186,8 @@
|
||||
disable_volume_snapshot: false,
|
||||
default_availability_zone: 'Any'
|
||||
},
|
||||
DEFAULT_BOOT_SOURCE: 'image'
|
||||
DEFAULT_BOOT_SOURCE: 'image',
|
||||
OPENSTACK_SERVER_DEFAULT_USER_DATA: ''
|
||||
};
|
||||
IMAGE = {type: 'image', label: 'Image', selected: true};
|
||||
VOLUME = {type: 'volume', label: 'Volume', selected: false};
|
||||
@ -883,7 +884,7 @@
|
||||
// This is here to ensure that as people add/change items, they
|
||||
// don't forget to implement tests for them.
|
||||
it('has the right number of properties', function() {
|
||||
expect(Object.keys(model.newInstanceSpec).length).toBe(22);
|
||||
expect(Object.keys(model.newInstanceSpec).length).toBe(23);
|
||||
});
|
||||
|
||||
it('sets availability zone to null', function() {
|
||||
@ -910,6 +911,10 @@
|
||||
expect(model.newInstanceSpec.user_data).toBe('');
|
||||
});
|
||||
|
||||
it('sets default user data to an empty string', function() {
|
||||
expect(model.newInstanceSpec.default_user_data).toBe('');
|
||||
});
|
||||
|
||||
it('sets disk config to AUTO', function() {
|
||||
expect(model.newInstanceSpec.disk_config).toBe('AUTO');
|
||||
});
|
||||
|
@ -256,6 +256,9 @@ LAUNCH_INSTANCE_DEFAULTS = {
|
||||
'default_availability_zone': 'Any',
|
||||
}
|
||||
|
||||
# A Django template astring that will be used as default user_data for new VMs
|
||||
OPENSTACK_SERVER_DEFAULT_USER_DATA = ""
|
||||
|
||||
# The absolute path to the directory where message files are collected.
|
||||
# The message file must have a .json file extension. When the user logins to
|
||||
# horizon, the message files collected are processed and displayed to the user.
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The new setting ``OPENSTACK_SERVER_DEFAULT_USER_DATA`` allows an
|
||||
administrator to specify a default user data (e.g. comments or
|
||||
instructions for cloudinit) for new VMs. It can be a raw string or string
|
||||
template that accepts the request.
|
Loading…
Reference in New Issue
Block a user