Merge "Adding identity domains table"
This commit is contained in:
commit
8962d7b8cc
@ -439,11 +439,17 @@ Default::
|
||||
'images_panel': True,
|
||||
'flavors_panel': False,
|
||||
'users_panel': False,
|
||||
'domains_panel': False
|
||||
}
|
||||
|
||||
A dictionary of currently available AngularJS features. This allows simple
|
||||
toggling of legacy or rewritten features, such as new panels, workflows etc.
|
||||
|
||||
.. note::
|
||||
|
||||
If you toggle 'domains_panel' to True, you also need to enable the setting
|
||||
of OPENSTACK_KEYSTONE_DEFAULT_DOMAIN and add OPENSTACK_KEYSTONE_DEFAULT_DOMAIN
|
||||
to REST_API_REQUIRED_SETTINGS.
|
||||
|
||||
.. _available_themes:
|
||||
|
||||
|
@ -12,14 +12,24 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from openstack_dashboard.dashboards.identity.domains import views
|
||||
from horizon.browsers import views
|
||||
|
||||
from openstack_dashboard.dashboards.identity.domains import views as legacyView
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^create$', views.CreateDomainView.as_view(), name='create'),
|
||||
url(r'^(?P<domain_id>[^/]+)/update/$',
|
||||
views.UpdateDomainView.as_view(), name='update')
|
||||
]
|
||||
if settings.ANGULAR_FEATURES.get('domains_panel'):
|
||||
title = _("Domains")
|
||||
urlpatterns = [
|
||||
url('', views.AngularIndexView.as_view(title=title), name='index'),
|
||||
]
|
||||
else:
|
||||
urlpatterns = [
|
||||
url(r'^$', legacyView.IndexView.as_view(), name='index'),
|
||||
url(r'^create$', legacyView.CreateDomainView.as_view(), name='create'),
|
||||
url(r'^(?P<domain_id>[^/]+)/update/$',
|
||||
legacyView.UpdateDomainView.as_view(), name='update')
|
||||
]
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2016 NEC Corporation.
|
||||
*
|
||||
* 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 overview
|
||||
* @ngname horizon.cluster.receivers.details
|
||||
*
|
||||
* @description
|
||||
* Provides details features for domain.
|
||||
*/
|
||||
angular.module('horizon.dashboard.identity.domains.details', [
|
||||
'horizon.framework.conf',
|
||||
'horizon.app.core'
|
||||
])
|
||||
.run(registerDomainDetails);
|
||||
|
||||
registerDomainDetails.$inject = [
|
||||
'horizon.dashboard.identity.domains.basePath',
|
||||
'horizon.dashboard.identity.domains.resourceType',
|
||||
'horizon.app.core.openstack-service-api.keystone',
|
||||
'horizon.framework.conf.resource-type-registry.service'
|
||||
];
|
||||
|
||||
function registerDomainDetails(basePath, domainResourceType, keystone, registry) {
|
||||
registry.getResourceType(domainResourceType)
|
||||
.setLoadFunction(loadFunction)
|
||||
.detailsViews.append({
|
||||
id: 'domainDetailsOverview',
|
||||
name: gettext('Overview'),
|
||||
template: basePath + 'details/overview.html'
|
||||
});
|
||||
|
||||
function loadFunction(identifier) {
|
||||
return keystone.getDomain(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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';
|
||||
|
||||
describe('Identity domains details module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.identity.domains.details')).toBeDefined();
|
||||
});
|
||||
|
||||
var registry, resource;
|
||||
beforeEach(module('horizon.framework'));
|
||||
beforeEach(module('horizon.dashboard.identity.domains'));
|
||||
beforeEach(inject(function($injector) {
|
||||
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
|
||||
}));
|
||||
|
||||
it('should be loaded', function() {
|
||||
resource = registry.getResourceType('OS::Keystone::Domain');
|
||||
expect(resource.detailsViews[0].id).toBe('domainDetailsOverview');
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
@ -0,0 +1,5 @@
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Keystone::Domain"
|
||||
item="item"
|
||||
property-groups="[['id', 'name'], ['description', 'enabled']]">
|
||||
</hz-resource-property-list>
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2016 NEC Corporation.
|
||||
*
|
||||
* 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";
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.identity.domains')
|
||||
.controller('DomainOverviewController', DomainOverviewController);
|
||||
|
||||
DomainOverviewController.$inject = [
|
||||
'horizon.dashboard.identity.domains.resourceType',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'$scope'
|
||||
];
|
||||
|
||||
function DomainOverviewController(
|
||||
domainResourceType,
|
||||
registry,
|
||||
$scope
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.domain = {};
|
||||
ctrl.resourceType = registry.getResourceType(domainResourceType);
|
||||
|
||||
// assign a controller attribute once the RoutedDetailsViewController
|
||||
// has loaded the domain for us
|
||||
$scope.context.loadPromise.then(onGetDomain);
|
||||
|
||||
function onGetDomain(domain) {
|
||||
ctrl.domain = domain.data;
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* 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';
|
||||
|
||||
describe('Identity domains details module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.identity.domains.details')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('domain overview controller', function() {
|
||||
var ctrl, $scope;
|
||||
|
||||
beforeEach(module('horizon.dashboard.identity.domains'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(inject(function($controller, $injector, $q, _$rootScope_) {
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({data: {id: '1234', 'name': 'test'}});
|
||||
ctrl = $controller('DomainOverviewController',
|
||||
{'$scope': {context: {loadPromise: deferred.promise}}}
|
||||
);
|
||||
$scope = _$rootScope_.$new();
|
||||
}));
|
||||
|
||||
it('sets ctrl.resourceType', function() {
|
||||
expect(ctrl.resourceType).toBeDefined();
|
||||
});
|
||||
|
||||
it('sets ctrl.domain', inject(function() {
|
||||
$scope.$apply();
|
||||
expect(ctrl.domain).toBeDefined();
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -0,0 +1,14 @@
|
||||
<div ng-controller="DomainOverviewController as ctrl">
|
||||
<div class="row">
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Domain</h3>
|
||||
<hr>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Keystone::Domain"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.domain"
|
||||
property-groups="[['id', 'name', 'description', 'enabled']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2016 NEC Corporation.
|
||||
*
|
||||
* 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 overview
|
||||
* @ngname horizon.dashboard.identity.domains
|
||||
*
|
||||
* @description
|
||||
* Provides all of the services and widgets required
|
||||
* to support and display domains related content.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.identity.domains', [
|
||||
'ngRoute',
|
||||
'horizon.dashboard.identity.domains.details'
|
||||
])
|
||||
.constant('horizon.dashboard.identity.domains.resourceType', 'OS::Keystone::Domain')
|
||||
.run(run)
|
||||
.config(config);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.identity.domains.service',
|
||||
'horizon.dashboard.identity.domains.basePath',
|
||||
'horizon.dashboard.identity.domains.resourceType'
|
||||
];
|
||||
|
||||
function run(registry, domainService, basePath, domainResourceType) {
|
||||
registry.getResourceType(domainResourceType)
|
||||
.setNames(gettext('Domain'), gettext('Domains'))
|
||||
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
|
||||
.setProperties(domainProperties())
|
||||
.setListFunction(domainService.listDomains)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
sortDefault: true,
|
||||
urlFunction: domainService.getDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'description',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'id',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'enabled',
|
||||
priority: 1
|
||||
});
|
||||
}
|
||||
|
||||
function domainProperties() {
|
||||
return {
|
||||
name: { label: gettext('Name'), filters: ['noName'] },
|
||||
description: { label: gettext('Description'), filters: ['noValue'] },
|
||||
id: { label: gettext('ID'), filters: ['noValue'] },
|
||||
enabled: { label: gettext('Enabled'), filters: ['yesno'] }
|
||||
};
|
||||
}
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider',
|
||||
'$routeProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name config
|
||||
* @param {Object} $provide
|
||||
* @param {Object} $windowProvider
|
||||
* @param {Object} $routeProvider
|
||||
* @description Routes used by this module.
|
||||
* @returns {undefined} Returns nothing
|
||||
*/
|
||||
function config($provide, $windowProvider, $routeProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'dashboard/identity/domains/';
|
||||
$provide.constant('horizon.dashboard.identity.domains.basePath', path);
|
||||
|
||||
$routeProvider.when('/identity/domains', {
|
||||
templateUrl: path + 'panel.html'
|
||||
});
|
||||
}
|
||||
})();
|
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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';
|
||||
|
||||
describe('Identity domains module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.identity.domains')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2016 NEC Corporation.
|
||||
*
|
||||
* 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";
|
||||
|
||||
angular.module('horizon.dashboard.identity.domains')
|
||||
.factory('horizon.dashboard.identity.domains.service', domainService);
|
||||
|
||||
domainService.$inject = [
|
||||
'$q',
|
||||
'horizon.app.core.openstack-service-api.keystone',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.app.core.openstack-service-api.settings'
|
||||
];
|
||||
|
||||
/*
|
||||
* @ngdoc factory
|
||||
* @name horizon.dashboard.identity.domains.service
|
||||
*
|
||||
* @description
|
||||
* This service provides functions that are used through the Domains
|
||||
* features. These are primarily used in the module registrations
|
||||
* but do not need to be restricted to such use. Each exposed function
|
||||
* is documented below.
|
||||
*/
|
||||
function domainService($q, keystone, policy, settingsService) {
|
||||
return {
|
||||
getDetailsPath: getDetailsPath,
|
||||
getDomainPromise: getDomainPromise,
|
||||
listDomains: listDomains
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getDetailsPath
|
||||
* @param item {Object} - The domain object
|
||||
* @description
|
||||
* Given an Domain object, returns the relative path to the details
|
||||
* view.
|
||||
*/
|
||||
function getDetailsPath(item) {
|
||||
return 'project/ngdetails/OS::Keystone::Domain/' + item.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name listDomains
|
||||
* @description
|
||||
* Returns list of domains. This is used in displaying lists of Domains.
|
||||
* In this case, we need to modify the API's response by adding a
|
||||
* composite value called 'trackBy' to assist the display mechanism
|
||||
* when updating rows.
|
||||
*/
|
||||
function listDomains() {
|
||||
var defaultDomain = null;
|
||||
var KEYSTONE_DEFAULT_DOMAIN = null;
|
||||
|
||||
return $q.all([
|
||||
keystone.getDomain('default'),
|
||||
settingsService.getSetting('OPENSTACK_KEYSTONE_DEFAULT_DOMAIN')
|
||||
]).then(allowed);
|
||||
|
||||
function allowed(results) {
|
||||
defaultDomain = results[0].data;
|
||||
KEYSTONE_DEFAULT_DOMAIN = results[1];
|
||||
|
||||
var rules = [['identity', 'identity:list_domains']];
|
||||
return policy.ifAllowed({ rules: rules }).then(policySuccess, policyFailed);
|
||||
}
|
||||
|
||||
function policySuccess() {
|
||||
if (isDefaultDomain()) {
|
||||
// In case that a user is cloud admin and context is Keystone default domain.
|
||||
return keystone.getDomains().then(getDomainSuccess);
|
||||
} else {
|
||||
// In case that a user is cloud admin but has a specific domain scope.
|
||||
return keystone.getDomain(defaultDomain.id).then(getDomainSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
function policyFailed() {
|
||||
// In case that a user doesn't have a privilege of list_domains.
|
||||
return keystone.getDomain(defaultDomain.id).then(getDomainSuccess);
|
||||
}
|
||||
|
||||
function getDomainSuccess(response) {
|
||||
if (!angular.isArray(response.data.items)) {
|
||||
// the result of getDomain is not array.
|
||||
response.data.items = [response.data];
|
||||
}
|
||||
return {data: {items: response.data.items.map(modifyDomain)}};
|
||||
|
||||
function modifyDomain(domain) {
|
||||
domain.trackBy = domain.id;
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
function isDefaultDomain() {
|
||||
return defaultDomain.name === KEYSTONE_DEFAULT_DOMAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getDomainPromise
|
||||
* @description
|
||||
* Given an id, returns a promise for the domain data.
|
||||
*/
|
||||
function getDomainPromise(identifier) {
|
||||
return keystone.getDomain(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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";
|
||||
|
||||
describe('domain service', function() {
|
||||
var service, $scope;
|
||||
beforeEach(module('horizon.dashboard.identity.domains'));
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.dashboard.identity.domains.service');
|
||||
}));
|
||||
|
||||
it("getDetailsPath creates urls using the item's ID", function() {
|
||||
var myItem = {id: "1234"};
|
||||
expect(service.getDetailsPath(myItem)).toBe('project/ngdetails/OS::Keystone::Domain/1234');
|
||||
});
|
||||
|
||||
describe('listDomains', function() {
|
||||
var keystone, setting, policy;
|
||||
beforeEach(inject(function($injector) {
|
||||
keystone = $injector.get('horizon.app.core.openstack-service-api.keystone');
|
||||
setting = $injector.get('horizon.app.core.openstack-service-api.settings');
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
}));
|
||||
|
||||
it("allowed list_domain and default domain scope", inject(function($q, _$rootScope_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
var deferredGetDomain = $q.defer();
|
||||
var deferredGetDomains = $q.defer();
|
||||
var deferredSetting = $q.defer();
|
||||
var deferredPolicy = $q.defer();
|
||||
spyOn(keystone, 'getDomain').and.returnValue(deferredGetDomain.promise);
|
||||
spyOn(keystone, 'getDomains').and.returnValue(deferredGetDomains.promise);
|
||||
spyOn(setting, 'getSetting').and.returnValue(deferredSetting.promise);
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(deferredPolicy.promise);
|
||||
|
||||
var result = service.listDomains({});
|
||||
|
||||
deferredGetDomain.resolve({data: {id: 'default', name: 'Default'}});
|
||||
deferredGetDomains.resolve({data: {items: [{id: '1234', name: 'test_domain1'}]}});
|
||||
deferredSetting.resolve("Default");
|
||||
deferredPolicy.resolve({"allowed": true});
|
||||
|
||||
$scope.$apply();
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1234');
|
||||
}));
|
||||
|
||||
it("allowed list_domain and not domain scope", inject(function($q, _$rootScope_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
var deferredGetDomain = $q.defer();
|
||||
var deferredSetting = $q.defer();
|
||||
var deferredPolicy = $q.defer();
|
||||
spyOn(keystone, 'getDomain').and.returnValue(deferredGetDomain.promise);
|
||||
spyOn(setting, 'getSetting').and.returnValue(deferredSetting.promise);
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(deferredPolicy.promise);
|
||||
|
||||
var result = service.listDomains({});
|
||||
|
||||
deferredGetDomain.resolve({data: {id: '1234', name: 'test_domain1'}});
|
||||
deferredSetting.resolve("Default");
|
||||
deferredPolicy.resolve({"allowed": true});
|
||||
|
||||
$scope.$apply();
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1234');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('getDomainPromise', function() {
|
||||
it("provides a promise", inject(function($q, $injector) {
|
||||
var keystone = $injector.get('horizon.app.core.openstack-service-api.keystone');
|
||||
var deferred = $q.defer();
|
||||
spyOn(keystone, 'getDomain').and.returnValue(deferred.promise);
|
||||
var result = service.getDomainPromise({});
|
||||
deferred.resolve({id: 1, name: 'test_domain'});
|
||||
expect(keystone.getDomain).toHaveBeenCalled();
|
||||
expect(result.$$state.value.name).toBe('test_domain');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,4 @@
|
||||
<hz-resource-panel resource-type-name="OS::Keystone::Domain">
|
||||
<hz-resource-table resource-type-name="OS::Keystone::Domain">
|
||||
</hz-resource-table>
|
||||
</hz-resource-panel>
|
@ -26,6 +26,7 @@
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.identity', [
|
||||
'horizon.dashboard.identity.domains',
|
||||
'horizon.dashboard.identity.users',
|
||||
'horizon.dashboard.identity.projects',
|
||||
'horizon.dashboard.identity.roles'
|
||||
|
@ -747,7 +747,8 @@ SECURITY_GROUP_RULES = {
|
||||
# See: https://wiki.openstack.org/wiki/Horizon/RESTAPI
|
||||
REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES',
|
||||
'LAUNCH_INSTANCE_DEFAULTS',
|
||||
'OPENSTACK_IMAGE_FORMATS']
|
||||
'OPENSTACK_IMAGE_FORMATS',
|
||||
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN']
|
||||
|
||||
# Additional settings can be made available to the client side for
|
||||
# extensibility by specifying them in REST_API_ADDITIONAL_SETTINGS
|
||||
|
Loading…
Reference in New Issue
Block a user