Read access to config via REST
We have a lot of new angular widgets and panels coming, and some of them will need access to configs stored in settings. Right now, the default way to get them is through _conf.html or _script.html. We should really fetch them through the new REST layer instead. This ensures we are following the same pattern already set up for angular panels and services. This version: - add localstorage for caching config front-end Change-Id: I94ce8ef3e8367be99bbba2f6ddd7e4529d819d58 Co-Authored-By: Richard Jones <r1chardj0n3s@gmail.com> Implements: blueprint config-restful
This commit is contained in:
parent
f38965ec30
commit
12a7f1d3fc
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2015, Rackspace, US, Inc.
|
||||
|
||||
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 a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name hz.api.configAPI
|
||||
* @description Provides access to dashboard configuration.
|
||||
*/
|
||||
function ConfigAPI(apiService) {
|
||||
|
||||
/**
|
||||
* @name hz.api.configAPI.getUserDefaults
|
||||
* @description
|
||||
* Get the default user configuration settings.
|
||||
*
|
||||
* Returns an object with user configuration settings.
|
||||
*/
|
||||
this.getUserDefaults = function() {
|
||||
return apiService.get('/api/config/user/')
|
||||
.success(function(data) {
|
||||
// store config in localStorage
|
||||
// should be call only when defaults are needed
|
||||
// or when user wants to reset it
|
||||
localStorage.user_config = angular.toJson(data);
|
||||
})
|
||||
.error(function () {
|
||||
horizon.alert('error', gettext('Unable to retrieve user configuration.'));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @name hz.api.configAPI.getAdminDefaults
|
||||
* @description
|
||||
* Get the default admin configuration settings.
|
||||
*
|
||||
* Returns an object with admin configuration settings.
|
||||
*/
|
||||
this.getAdminDefaults = function(params) {
|
||||
return apiService.get('/api/config/admin/')
|
||||
.success(function(data) {
|
||||
// store this in localStorage
|
||||
// should be call once each page load
|
||||
localStorage.admin_config = angular.toJson(data);
|
||||
})
|
||||
.error(function () {
|
||||
horizon.alert('error', gettext('Unable to retrieve admin configuration.'));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Register it with the API module so that anybody using the
|
||||
// API module will have access to the Config APIs.
|
||||
angular.module('hz.api')
|
||||
.service('configAPI', ['apiService', ConfigAPI]);
|
||||
}());
|
|
@ -21,6 +21,7 @@
|
|||
<script src='{{ STATIC_URL }}horizon/js/angular/hz.api.module.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.service.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.cinder.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.config.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.glance.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.keystone.js'></script>
|
||||
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.nova.js'></script>
|
||||
|
|
|
@ -23,6 +23,7 @@ in https://wiki.openstack.org/wiki/APIChangeGuidelines.
|
|||
|
||||
# import REST API modules here
|
||||
import cinder #flake8: noqa
|
||||
import config #flake8: noqa
|
||||
import glance #flake8: noqa
|
||||
import keystone #flake8: noqa
|
||||
import network #flake8: noqa
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from django.views import generic
|
||||
|
||||
from horizon import conf
|
||||
|
||||
from openstack_dashboard.api.rest import urls
|
||||
from openstack_dashboard.api.rest import utils as rest_utils
|
||||
|
||||
|
||||
# properties we know are admin config
|
||||
admin_configs = ['ajax_queue_limit', 'ajax_poll_interval',
|
||||
'user_home', 'help_url',
|
||||
'password_autocomplete', 'disable_password_reveal']
|
||||
|
||||
# properties we know are user config
|
||||
# this is a white list of keys under HORIZON_CONFIG in settings.pys
|
||||
# that we want to pass onto client
|
||||
user_configs = ['auto_fade_alerts', 'modal_backdrop']
|
||||
|
||||
|
||||
@urls.register
|
||||
class DefaultUserConfigs(generic.View):
|
||||
"""API for retrieving user configurations.
|
||||
|
||||
This API returns read-only-default configuration values.
|
||||
This configuration object is ideally fetched once per application life
|
||||
or when a user needs to restore the default values.
|
||||
Examples of user config: modal_backdrop, disable_password_reveal
|
||||
"""
|
||||
url_regex = r'config/user/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get default user configurations
|
||||
"""
|
||||
config = {}
|
||||
for key in user_configs:
|
||||
config[key] = conf.HORIZON_CONFIG.get(key, None)
|
||||
return config
|
||||
|
||||
|
||||
@urls.register
|
||||
class AdminConfigs(generic.View):
|
||||
"""API for retrieving admin configurations.
|
||||
|
||||
This API returns read-only admin configuration values.
|
||||
This configuration object can be fetched as needed.
|
||||
Examples of admin config: help_url, user_home
|
||||
"""
|
||||
url_regex = r'config/admin/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get read-only admin configurations
|
||||
"""
|
||||
config = {}
|
||||
for key in admin_configs:
|
||||
config[key] = conf.HORIZON_CONFIG.get(key, None)
|
||||
return config
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2015 IBM Corp.
|
||||
#
|
||||
# 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 a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from horizon import conf
|
||||
|
||||
from openstack_dashboard.api.rest import config
|
||||
from openstack_dashboard.test.api_tests import rest_test_utils as util
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class ConfigRestTestCase(test.RestAPITestCase):
|
||||
|
||||
def assertContains(self, response, expected_content):
|
||||
if response.find(expected_content) > 0:
|
||||
return
|
||||
self.fail('%s does not contain %s' %
|
||||
(response, expected_content))
|
||||
|
||||
def assertNotContains(self, response, expected_content):
|
||||
if response.find(expected_content) < 0:
|
||||
return
|
||||
self.fail('%s contains %s when it should not' %
|
||||
(response, expected_content))
|
||||
|
||||
def test_user_config_get(self):
|
||||
user_config = {"modal_backdrop": "static"}
|
||||
content = '"modal_backdrop": "static"'
|
||||
with mock.patch.dict(conf.HORIZON_CONFIG, user_config):
|
||||
request = util.construct_request()
|
||||
response = config.DefaultUserConfigs().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertContains(response.content, content)
|
||||
|
||||
def test_admin_config_get(self):
|
||||
admin_config = {"user_home": "somewhere.com"}
|
||||
content = '"user_home": "somewhere.com"'
|
||||
with mock.patch.dict(conf.HORIZON_CONFIG, admin_config):
|
||||
request = util.construct_request()
|
||||
response = config.AdminConfigs().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertContains(response.content, content)
|
||||
|
||||
def test_ignore_list(self):
|
||||
ignore_config = {"password_validator": "someobject"}
|
||||
content = '"password_validator": "someobject"'
|
||||
with mock.patch.dict(conf.HORIZON_CONFIG, ignore_config):
|
||||
request = util.construct_request()
|
||||
response = config.AdminConfigs().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertNotContains(response.content, content)
|
Loading…
Reference in New Issue