ngReorg - Move API files to openstack_dashboard

This commit moves the Angular-based API services to the
openstack_dashboard directory.

It also simplifies the naming scheme for the Angular-based
API modules.

Fixes all JSCS issues in files that were modified by this patch.

This is one step in a larger effort to restructure the Angular
source. See https://review.openstack.org/#/c/176152/ for the
full set of planned changes.

Change-Id: I4200336508761fb0155be422ebcecd4bf2907035
Closes-Bug: #1446886
This commit is contained in:
Ryan Peters 2015-06-08 10:43:29 -05:00
parent bb4626f0f9
commit 14eb8040da
35 changed files with 560 additions and 524 deletions

View File

@ -66,9 +66,7 @@ module.exports = function(config) {
// from jasmine_tests.py; only those that are deps for others // from jasmine_tests.py; only those that are deps for others
'horizon/js/horizon.js', 'horizon/js/horizon.js',
'horizon/js/angular/hz.api.module.js', '../../openstack_dashboard/static/openstack-service-api/openstack-service-api.module.js',
'horizon/js/angular/services/**/*.js',
'horizon/js/angular/hz.api.module.js',
'dashboard-app/dashboard-app.module.js', 'dashboard-app/dashboard-app.module.js',
'dashboard-app/**/*.js', 'dashboard-app/**/*.js',
'auth/auth.module.js', 'auth/auth.module.js',

View File

@ -5,7 +5,7 @@
angular.module('horizon.dashboard-app', [ angular.module('horizon.dashboard-app', [
'horizon.framework', 'horizon.framework',
'horizon.auth', 'horizon.auth',
'hz.api', 'horizon.openstack-service-api',
'ngCookies'].concat(angularModuleExtension)) 'ngCookies'].concat(angularModuleExtension))
.constant('horizon.dashboard-app.conf', { .constant('horizon.dashboard-app.conf', {

View File

@ -16,6 +16,13 @@ limitations under the License.
(function () { (function () {
'use strict'; 'use strict';
angular
.module('horizon.framework.util.http', [])
.service('horizon.framework.util.http.service', ApiService);
ApiService.$inject = ['$http'];
function ApiService($http) { function ApiService($http) {
var httpCall = function (method, url, data, config) { var httpCall = function (method, url, data, config) {
@ -49,7 +56,4 @@ limitations under the License.
return httpCall('DELETE', url, data, config); return httpCall('DELETE', url, data, config);
}; };
} }
angular.module('hz.api.common', [])
.service('hz.api.common.service', ['$http', '$log', ApiService]);
}()); }());

View File

@ -1,18 +1,18 @@
(function () { (function () {
'use strict'; 'use strict';
describe('hz.api.common module', function() { describe('horizon.framework.util.http module', function() {
it('should have been defined', function () { it('should have been defined', function () {
expect(angular.module('hz.api.common')).toBeDefined(); expect(angular.module('horizon.framework.util.http')).toBeDefined();
}); });
}); });
describe('api service', function () { describe('api service', function () {
var api, $httpBackend; var api, $httpBackend;
beforeEach(module('hz.api.common')); beforeEach(module('horizon.framework.util.http'));
beforeEach(inject(function ($injector) { beforeEach(inject(function ($injector) {
api = $injector.get('hz.api.common.service'); api = $injector.get('horizon.framework.util.http.service');
$httpBackend = $injector.get('$httpBackend'); $httpBackend = $injector.get('$httpBackend');
})); }));

View File

@ -1,9 +1,10 @@
(function () { (function () {
'use strict'; 'use strict';
angular.module('horizon.framework.util', [ angular.module('horizon.framework.util', [
'horizon.framework.util.bind-scope', 'horizon.framework.util.bind-scope',
'horizon.framework.util.filters', 'horizon.framework.util.filters',
'horizon.framework.util.http',
'horizon.framework.util.i18n', 'horizon.framework.util.i18n',
'horizon.framework.util.tech-debt', 'horizon.framework.util.tech-debt',
'horizon.framework.util.workflow', 'horizon.framework.util.workflow',

View File

@ -1,200 +0,0 @@
/**
* 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.
*/
(function () {
'use strict';
/**
* @ngdoc service
* @name hz.api.NeutronAPI
* @description Provides access to Neutron APIs.
*/
function NeutronAPI(apiService, toastService) {
// Networks
/**
* @name hz.api.neturonAPI.getNetworks
* @description
* Get a list of networks for a tenant.
*
* The listing result is an object with property "items". Each item is
* a network.
*/
this.getNetworks = function() {
return apiService.get('/api/neutron/networks/')
.error(function () {
toastService.add('error', gettext('Unable to retrieve the networks.'));
});
};
/**
* @name hz.api.neutronAPI.createNetwork
* @description
* Create a new network.
* @returns The new network object on success.
*
* @param {Object} newNetwork
* The network to create. Required.
*
* Example new network object
* {
* "name": "myNewNetwork",
* "admin_state_up": true,
* "net_profile_id" : "asdsarafssdaser",
* "shared": true,
* "tenant_id": "4fd44f30292945e481c7b8a0c8908869
* }
*
* Description of properties on the network object
*
* @property {string} newNetwork.name
* The name of the new network. Optional.
*
* @property {boolean} newNetwork.admin_state_up
* The administrative state of the network, which is up (true) or
* down (false). Optional.
*
* @property {string} newNetwork.net_profile_id
* The network profile id. Optional.
*
* @property {boolean} newNetwork.shared
* Indicates whether this network is shared across all tenants.
* By default, only adminstative users can change this value. Optional.
*
* @property {string} newNetwork.tenant_id
* The UUID of the tenant that will own the network. This tenant can
* be different from the tenant that makes the create network request.
* However, only administative users can specify a tenant ID other than
* their own. You cannot change this value through authorization
* policies. Optional.
*
*/
this.createNetwork = function(newNetwork) {
return apiService.post('/api/neutron/networks/', newNetwork)
.error(function () {
toastService.add('error', gettext('Unable to create the network.'));
});
};
// Subnets
/**
* @name hz.api.neutronAPI.getSubnets
* @description
* Get a list of subnets for a network.
*
* The listing result is an object with property "items". Each item is
* a subnet.
*
* @param {string} network_id
* The network id to retrieve subnets for. Required.
*/
this.getSubnets = function(network_id) {
return apiService.get('/api/neutron/subnets/', network_id)
.error(function () {
toastService.add('error', gettext('Unable to retrieve the subnets.'));
});
};
/**
* @name hz.api.neutronAPI.createSubnet
* @description
* Create a Subnet for given Network.
* @returns The JSON representation of Subnet on success.
*
* @param {Object} newSubnet
* The subnet to create.
*
* Example new subnet object
* {
* "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
* "ip_version": 4,
* "cidr": "192.168.199.0/24",
* "name": "mySubnet",
* "tenant_id": "4fd44f30292945e481c7b8a0c8908869,
* "allocation_pools": [
* {
* "start": "192.168.199.2",
* "end": "192.168.199.254"
* }
* ],
* "gateway_ip": "192.168.199.1",
* "id": "abce",
* "enable_dhcp": true,
* }
*
* Description of properties on the subnet object
* @property {string} newSubnet.network_id
* The id of the attached network. Required.
*
* @property {number} newSubnet.ip_version
* The IP version, which is 4 or 6. Required.
*
* @property {string} newSubnet.cidr
* The CIDR. Required.
*
* @property {string} newSubnet.name
* The name of the new subnet. Optional.
*
* @property {string} newSubnet.tenant_id
* The ID of the tenant who owns the network. Only administrative users
* can specify a tenant ID other than their own. Optional.
*
* @property {string|Array} newSubnet.allocation_pools
* The start and end addresses for the allocation pools. Optional.
*
* @property {string} newSubnet.gateway_ip
* The gateway IP address. Optional.
*
* @property {string} newSubnet.id
* The ID of the subnet. Optional.
*
* @property {boolean} newSubnet.enable_dhcp
* Set to true if DHCP is enabled and false if DHCP is disabled. Optional.
*
*/
this.createSubnet = function(newSubnet) {
return apiService.post('/api/neutron/subnets/', newSubnet)
.error(function () {
toastService.add('error', gettext('Unable to create the subnet.'));
});
};
// Ports
/**
* @name hz.api.neutronAPI.getPorts
* @description
* Get a list of ports for a network.
*
* The listing result is an object with property "items". Each item is
* a port.
*
* @param {string} network_id
* The network id to retrieve ports for. Required.
*/
this.getPorts = function(network_id) {
return apiService.get('/api/neutron/ports/', network_id)
.error(function () {
toastService.add('error', gettext('Unable to retrieve the ports.'));
});
};
}
angular.module('hz.api')
.service('hz.api.neutron', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', NeutronAPI]);
}());

View File

@ -17,16 +17,15 @@ from horizon.test import helpers as test
class ServicesTests(test.JasmineTests): class ServicesTests(test.JasmineTests):
sources = [ sources = [
'horizon/js/horizon.js', 'horizon/js/horizon.js',
'horizon/js/angular/hz.api.module.js', 'openstack-service-api/openstack-service-api.module.js',
'horizon/js/angular/services/hz.api.common.js', 'openstack-service-api/settings.service.js',
'horizon/js/angular/services/hz.api.cinder.js', 'openstack-service-api/cinder.service.js',
'horizon/js/angular/services/hz.api.config.js', 'openstack-service-api/glance.service.js',
'horizon/js/angular/services/hz.api.glance.js', 'openstack-service-api/keystone.service.js',
'horizon/js/angular/services/hz.api.keystone.js', 'openstack-service-api/neutron.service.js',
'horizon/js/angular/services/hz.api.neutron.js', 'openstack-service-api/nova.service.js',
'horizon/js/angular/services/hz.api.nova.js', 'openstack-service-api/policy.service.js',
'horizon/js/angular/services/hz.api.policy.js', 'openstack-service-api/security-group.service.js',
'horizon/js/angular/services/hz.api.security-group.js',
'auth/auth.module.js', 'auth/auth.module.js',
'auth/login/login.module.js', 'auth/login/login.module.js',
@ -42,6 +41,7 @@ class ServicesTests(test.JasmineTests):
'framework/util/util.module.js', 'framework/util/util.module.js',
'framework/util/bind-scope/bind-scope.js', 'framework/util/bind-scope/bind-scope.js',
'framework/util/filters/filters.js', 'framework/util/filters/filters.js',
'framework/util/http/http.js',
'framework/util/i18n/i18n.js', 'framework/util/i18n/i18n.js',
'framework/util/validators/validators.js', 'framework/util/validators/validators.js',
'framework/util/workflow/workflow.js', 'framework/util/workflow/workflow.js',
@ -73,21 +73,21 @@ class ServicesTests(test.JasmineTests):
'framework/widgets/toast/toast.factory.js', 'framework/widgets/toast/toast.factory.js',
] ]
specs = [ specs = [
'horizon/js/angular/services/hz.api.common.spec.js',
'horizon/js/angular/services/hz.api.common-test.spec.js',
'horizon/js/angular/services/hz.api.cinder.spec.js',
'horizon/js/angular/services/hz.api.config.spec.js',
'horizon/js/angular/services/hz.api.glance.spec.js',
'horizon/js/angular/services/hz.api.keystone.spec.js',
'horizon/js/angular/services/hz.api.neutron.spec.js',
'horizon/js/angular/services/hz.api.nova.spec.js',
'horizon/js/angular/services/hz.api.policy.spec.js',
'horizon/js/angular/services/hz.api.security-group.spec.js',
'auth/login/login.spec.js', 'auth/login/login.spec.js',
'openstack-service-api/common-test.spec.js',
'openstack-service-api/settings.service.spec.js',
'openstack-service-api/cinder.service.spec.js',
'openstack-service-api/glance.service.spec.js',
'openstack-service-api/keystone.service.spec.js',
'openstack-service-api/neutron.service.spec.js',
'openstack-service-api/nova.service.spec.js',
'openstack-service-api/policy.service.spec.js',
'openstack-service-api/security-group.service.spec.js',
'framework/util/bind-scope/bind-scope.spec.js', 'framework/util/bind-scope/bind-scope.spec.js',
'framework/util/filters/filters.spec.js', 'framework/util/filters/filters.spec.js',
'framework/util/http/http.spec.js',
'framework/util/i18n/i18n.spec.js', 'framework/util/i18n/i18n.spec.js',
'framework/util/tech-debt/helper-functions.spec.js', 'framework/util/tech-debt/helper-functions.spec.js',
'framework/util/validators/validators.spec.js', 'framework/util/validators/validators.spec.js',

View File

@ -64,6 +64,13 @@ module.exports = function(config) {
xstaticPath + 'spin/data/spin.js', xstaticPath + 'spin/data/spin.js',
xstaticPath + 'spin/data/spin.jquery.js', xstaticPath + 'spin/data/spin.jquery.js',
// TODO: Should these be mocked?
'../../horizon/static/horizon/js/horizon.js',
'../../horizon/static/framework/util/http/http.js',
'openstack-service-api/openstack-service-api.module.js',
'openstack-service-api/**/*.js',
// This one seems to have to come first. // This one seems to have to come first.
"dashboard/dashboard.module.js", "dashboard/dashboard.module.js",
"dashboard/workflow/workflow.js", "dashboard/workflow/workflow.js",

View File

@ -42,15 +42,15 @@
*/ */
.factory('cloudServices', [ .factory('cloudServices', [
'hz.api.cinder', 'horizon.openstack-service-api.cinder',
'hz.api.glance', 'horizon.openstack-service-api.glance',
'hz.api.keystone', 'horizon.openstack-service-api.keystone',
'hz.api.neutron', 'horizon.openstack-service-api.neutron',
'hz.api.nova', 'horizon.openstack-service-api.nova',
'hz.api.novaExtensions', 'horizon.openstack-service-api.novaExtensions',
'hz.api.security-group', 'horizon.openstack-service-api.security-group',
'hz.api.serviceCatalog', 'horizon.openstack-service-api.serviceCatalog',
'hz.api.settingsService', 'horizon.openstack-service-api.settings',
function (cinderAPI, function (cinderAPI,
glanceAPI, glanceAPI,

View File

@ -25,15 +25,15 @@
var cloudServices; var cloudServices;
beforeEach(module('hz.dashboard', function ($provide) { beforeEach(module('hz.dashboard', function ($provide) {
$provide.value('hz.api.cinder', {}); $provide.value('horizon.openstack-service-api.cinder', {});
$provide.value('hz.api.glance', {}); $provide.value('horizon.openstack-service-api.glance', {});
$provide.value('hz.api.keystone', {}); $provide.value('horizon.openstack-service-api.keystone', {});
$provide.value('hz.api.neutron', {}); $provide.value('horizon.openstack-service-api.neutron', {});
$provide.value('hz.api.nova', {}); $provide.value('horizon.openstack-service-api.nova', {});
$provide.value('hz.api.novaExtensions', {}); $provide.value('horizon.openstack-service-api.novaExtensions', {});
$provide.value('hz.api.security-group', {}); $provide.value('horizon.openstack-service-api.security-group', {});
$provide.value('hz.api.serviceCatalog', {}); $provide.value('horizon.openstack-service-api.serviceCatalog', {});
$provide.value('hz.api.settingsService', {}); $provide.value('horizon.openstack-service-api.settings', {});
})); }));
beforeEach(inject(function ($injector) { beforeEach(inject(function ($injector) {

View File

@ -159,7 +159,7 @@
*/ */
module.controller('LaunchInstanceCreateKeyPairCtrl', [ module.controller('LaunchInstanceCreateKeyPairCtrl', [
'$modalInstance', '$modalInstance',
'hz.api.nova', 'horizon.openstack-service-api.nova',
'horizon.framework.widgets.toast.service', 'horizon.framework.widgets.toast.service',
LaunchInstanceCreateKeyPairCtrl LaunchInstanceCreateKeyPairCtrl
]); ]);
@ -235,7 +235,7 @@
*/ */
module.controller('LaunchInstanceImportKeyPairCtrl', [ module.controller('LaunchInstanceImportKeyPairCtrl', [
'$modalInstance', '$modalInstance',
'hz.api.nova', 'horizon.openstack-service-api.nova',
'horizon.framework.widgets.toast.service', 'horizon.framework.widgets.toast.service',
LaunchInstanceImportKeyPairCtrl LaunchInstanceImportKeyPairCtrl
]); ]);

View File

@ -100,7 +100,7 @@
beforeEach(module(function ($provide) { beforeEach(module(function ($provide) {
$provide.value('$modalInstance', {}); $provide.value('$modalInstance', {});
$provide.value('hz.api.nova', {}); $provide.value('horizon.openstack-service-api.nova', {});
$provide.value('horizon.framework.widgets.toast.service', {}); $provide.value('horizon.framework.widgets.toast.service', {});
})); }));
@ -159,7 +159,7 @@
beforeEach(module(function ($provide) { beforeEach(module(function ($provide) {
$provide.value('$modalInstance', {}); $provide.value('$modalInstance', {});
$provide.value('hz.api.nova', {}); $provide.value('horizon.openstack-service-api.nova', {});
$provide.value('horizon.framework.widgets.toast.service', {}); $provide.value('horizon.framework.widgets.toast.service', {});
})); }));

View File

@ -28,14 +28,14 @@
*/ */
module.factory('launchInstanceModel', ['$q', '$log', module.factory('launchInstanceModel', ['$q', '$log',
'hz.api.cinder', 'horizon.openstack-service-api.cinder',
'hz.api.glance', 'horizon.openstack-service-api.glance',
'hz.api.keystone', 'horizon.openstack-service-api.keystone',
'hz.api.neutron', 'horizon.openstack-service-api.neutron',
'hz.api.nova', 'horizon.openstack-service-api.nova',
'hz.api.novaExtensions', 'horizon.openstack-service-api.novaExtensions',
'hz.api.security-group', 'horizon.openstack-service-api.security-group',
'hz.api.serviceCatalog', 'horizon.openstack-service-api.serviceCatalog',
function ($q, function ($q,
$log, $log,

View File

@ -29,7 +29,7 @@
beforeEach(module('hz.dashboard.launch-instance')); beforeEach(module('hz.dashboard.launch-instance'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
$provide.value('hz.api.glance', { $provide.value('horizon.openstack-service-api.glance', {
getImages: function() { getImages: function() {
var images = [ var images = [
{ container_format: 'aki', properties: {} }, { container_format: 'aki', properties: {} },
@ -55,7 +55,7 @@
} }
}); });
$provide.value('hz.api.nova', { $provide.value('horizon.openstack-service-api.nova', {
createServer: function(finalSpec) { createServer: function(finalSpec) {
return finalSpec; return finalSpec;
}, },
@ -99,7 +99,7 @@
} }
}); });
$provide.value('hz.api.security-group', { $provide.value('horizon.openstack-service-api.security-group', {
query: function() { query: function() {
var secGroups = [ var secGroups = [
{ name: 'security-group-1' }, { name: 'security-group-1' },
@ -113,7 +113,7 @@
} }
}); });
$provide.value('hz.api.neutron', { $provide.value('horizon.openstack-service-api.neutron', {
getNetworks: function() { getNetworks: function() {
var networks = [ { id: 'net-1' }, { id: 'net-2' } ]; var networks = [ { id: 'net-1' }, { id: 'net-2' } ];
@ -124,7 +124,7 @@
} }
}); });
$provide.value('hz.api.cinder', { $provide.value('horizon.openstack-service-api.cinder', {
getVolumes: function() { getVolumes: function() {
var volumes = [ { id: 'vol-1' }, { id: 'vol-2' } ]; var volumes = [ { id: 'vol-1' }, { id: 'vol-2' } ];
@ -143,7 +143,7 @@
} }
}); });
$provide.value('hz.api.serviceCatalog', { $provide.value('horizon.openstack-service-api.serviceCatalog', {
ifTypeEnabled: function(theType) { ifTypeEnabled: function(theType) {
var deferred = $q.defer(); var deferred = $q.defer();
@ -159,7 +159,7 @@
} }
}); });
$provide.value('hz.api.novaExtensions', { $provide.value('horizon.openstack-service-api.novaExtensions', {
ifNameEnabled: function() { ifNameEnabled: function() {
var deferred = $q.defer(); var deferred = $q.defer();
@ -173,7 +173,7 @@
} }
}); });
$provide.value('hz.api.keystone', {}); $provide.value('horizon.openstack-service-api.keystone', {});
})); }));
beforeEach(inject(function(launchInstanceModel, $rootScope, _$q_) { beforeEach(inject(function(launchInstanceModel, $rootScope, _$q_) {

View File

@ -36,7 +36,7 @@
return spec; return spec;
}; };
$provide.value('hz.api.serviceCatalog', {}); $provide.value('horizon.openstack-service-api.serviceCatalog', {});
$provide.value('horizon.framework.util.workflow.service', workflow); $provide.value('horizon.framework.util.workflow.service', workflow);
})); }));

View File

@ -34,7 +34,7 @@
* *
* Injected dependencies: * Injected dependencies:
* - $q * - $q
* - serviceCatalog hz.api.serviceCatalog * - serviceCatalog horizon.openstack-service-api.serviceCatalog
* *
* @param {Object} spec The input workflow specification object. * @param {Object} spec The input workflow specification object.
* @returns {Object} The decorated workflow specification object, the same * @returns {Object} The decorated workflow specification object, the same
@ -46,7 +46,7 @@
* *
*/ */
.factory('dashboardWorkflowDecorator', ['$q', 'hz.api.serviceCatalog', .factory('dashboardWorkflowDecorator', ['$q', 'horizon.openstack-service-api.serviceCatalog',
function ($q, serviceCatalog) { function ($q, serviceCatalog) {

View File

@ -16,9 +16,16 @@ limitations under the License.
(function () { (function () {
'use strict'; 'use strict';
angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.cinder', CinderAPI);
CinderAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.cinderAPI * @name horizon.openstack-service-api.cinder
* @description Provides direct access to Cinder APIs. * @description Provides direct access to Cinder APIs.
*/ */
function CinderAPI(apiService, toastService) { function CinderAPI(apiService, toastService) {
@ -26,7 +33,7 @@ limitations under the License.
// Volumes // Volumes
/** /**
* @name hz.api.cinderAPI.getVolumes * @name horizon.openstack-service-api.cinder.getVolumes
* @description * @description
* Get a list of volumes. * Get a list of volumes.
* *
@ -51,7 +58,7 @@ limitations under the License.
// Volume Snapshots // Volume Snapshots
/** /**
* @name hz.api.cinderAPI.getVolumeSnapshots * @name horizon.openstack-service-api.cinder.getVolumeSnapshots
* @description * @description
* Get a list of volume snapshots. * Get a list of volume snapshots.
* *
@ -75,9 +82,4 @@ limitations under the License.
}); });
}; };
} }
// Register it with the API module so that anybody using the
// API module will have access to the Cinder APIs.
angular.module('hz.api')
.service('hz.api.cinder', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', CinderAPI]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.cinder', function(cinderAPI) { beforeEach(inject(['horizon.openstack-service-api.cinder', function(cinderAPI) {
service = cinderAPI; service = cinderAPI;
}])); }]));

View File

@ -74,7 +74,7 @@
patch: angular.noop, patch: angular.noop,
delete: angular.noop }); delete: angular.noop });
angular.extend(toastService, { add: angular.noop }); angular.extend(toastService, { add: angular.noop });
$provide.value('hz.api.common.service', apiService); $provide.value('horizon.framework.util.http.service', apiService);
$provide.value('horizon.framework.widgets.toast.service', toastService); $provide.value('horizon.framework.widgets.toast.service', toastService);
} }

View File

@ -16,17 +16,24 @@ limitations under the License.
(function () { (function () {
'use strict'; 'use strict';
angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.glance', GlanceAPI);
GlanceAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.glanceAPI * @name horizon.openstack-service-api.glance
* @description Provides direct pass through to Glance with NO abstraction. * @description Provides direct pass through to Glance with NO abstraction.
*/ */
function GlanceAPI(apiService, toastService) { function GlanceAPI(apiService, toastService) {
// Images // Images
/** /**
* @name hz.api.glanceAPI.getImage * @name horizon.openstack-service-api.glance.getImage
* @description * @description
* Get a single image by ID * Get a single image by ID
* @param {string} id * @param {string} id
@ -36,12 +43,11 @@ limitations under the License.
return apiService.get('/api/glance/images/' + id) return apiService.get('/api/glance/images/' + id)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the image.')); toastService.add('error', gettext('Unable to retrieve the image.'));
}); });
}; };
/** /**
* @name hz.api.glanceAPI.getImages * @name horizon.openstack-service-api.glance.getImages
* @description * @description
* Get a list of images. * Get a list of images.
* *
@ -79,13 +85,13 @@ limitations under the License.
return apiService.get('/api/glance/images/', config) return apiService.get('/api/glance/images/', config)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the images.')); toastService.add('error', gettext('Unable to retrieve the images.'));
}); });
}; };
// Metadata Definitions - Namespaces // Metadata Definitions - Namespaces
/** /**
* @name hz.api.glanceAPI.getNamespaces * @name horizon.openstack-service-api.glance.getNamespaces
* @description * @description
* Get a list of metadata definition namespaces. * Get a list of metadata definition namespaces.
* *
@ -146,11 +152,4 @@ limitations under the License.
}; };
} }
// Register it with the API module so that anybody using the
// API module will have access to the Glance APIs.
angular.module('hz.api')
.service('hz.api.glance', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', GlanceAPI]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.glance', function(glanceAPI) { beforeEach(inject(['horizon.openstack-service-api.glance', function(glanceAPI) {
service = glanceAPI; service = glanceAPI;
}])); }]));

View File

@ -15,13 +15,21 @@ limitations under the License.
*/ */
(function () { (function () {
'use strict'; 'use strict';
angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.keystone', KeystoneAPI);
KeystoneAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
function KeystoneAPI(apiService, toastService) { function KeystoneAPI(apiService, toastService) {
// Users // Users
this.getUsers = function(params) { this.getUsers = function(params) {
var config = (params) ? {'params': params} : {}; var config = (params) ? {'params': params} : {};
return apiService.get('/api/keystone/users/', config) return apiService.get('/api/keystone/users/', config)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve users.')); toastService.add('error', gettext('Unable to retrieve the users.'));
}); });
}; };
@ -32,15 +40,15 @@ limitations under the License.
}); });
}; };
this.deleteUsers = function(user_ids) { this.deleteUsers = function(userIds) {
return apiService.delete('/api/keystone/users/', user_ids) return apiService.delete('/api/keystone/users/', userIds)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the users.')); toastService.add('error', gettext('Unable to delete the users.'));
}); });
}; };
/** /**
* @name hz.api.keystoneApi.getCurrentUserSession * @name horizon.openstack-service-api.keystone.getCurrentUserSession
* @description * @description
* Gets the current User Session Information * Gets the current User Session Information
* @example * @example
@ -74,8 +82,8 @@ limitations under the License.
}); });
}; };
this.getUser = function(user_id) { this.getUser = function(userId) {
return apiService.get('/api/keystone/users/' + user_id) return apiService.get('/api/keystone/users/' + userId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the user.')); toastService.add('error', gettext('Unable to retrieve the user.'));
}); });
@ -89,8 +97,8 @@ limitations under the License.
}); });
}; };
this.deleteUser = function(user_id) { this.deleteUser = function(userId) {
return apiService.delete('/api/keystone/users/' + user_id) return apiService.delete('/api/keystone/users/' + userId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the user.')); toastService.add('error', gettext('Unable to delete the user.'));
}); });
@ -111,15 +119,15 @@ limitations under the License.
}); });
}; };
this.deleteRoles = function(role_ids) { this.deleteRoles = function(roleIds) {
return apiService.delete('/api/keystone/roles/', role_ids) return apiService.delete('/api/keystone/roles/', roleIds)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the roles.')); toastService.add('error', gettext('Unable to delete the roles.'));
}); });
}; };
this.getRole = function(role_id) { this.getRole = function(roleId) {
return apiService.get('/api/keystone/roles/' + role_id) return apiService.get('/api/keystone/roles/' + roleId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the role.')); toastService.add('error', gettext('Unable to retrieve the role.'));
}); });
@ -133,8 +141,8 @@ limitations under the License.
}); });
}; };
this.deleteRole = function(role_id) { this.deleteRole = function(roleId) {
return apiService.delete('/api/keystone/roles/' + role_id) return apiService.delete('/api/keystone/roles/' + roleId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the role.')); toastService.add('error', gettext('Unable to delete the role.'));
}); });
@ -155,15 +163,15 @@ limitations under the License.
}); });
}; };
this.deleteDomains = function(domain_ids) { this.deleteDomains = function(domainIds) {
return apiService.delete('/api/keystone/domains/', domain_ids) return apiService.delete('/api/keystone/domains/', domainIds)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the domains.')); toastService.add('error', gettext('Unable to delete the domains.'));
}); });
}; };
this.getDomain = function(domain_id) { this.getDomain = function(domainId) {
return apiService.get('/api/keystone/domains/' + domain_id) return apiService.get('/api/keystone/domains/' + domainId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the domain.')); toastService.add('error', gettext('Unable to retrieve the domain.'));
}); });
@ -177,8 +185,8 @@ limitations under the License.
}); });
}; };
this.deleteDomain = function(domain_id) { this.deleteDomain = function(domainId) {
return apiService.delete('/api/keystone/domains/' + domain_id) return apiService.delete('/api/keystone/domains/' + domainId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the domain.')); toastService.add('error', gettext('Unable to delete the domain.'));
}); });
@ -200,15 +208,15 @@ limitations under the License.
}); });
}; };
this.deleteProjects = function(project_ids) { this.deleteProjects = function(projectIds) {
return apiService.delete('/api/keystone/projects/', project_ids) return apiService.delete('/api/keystone/projects/', projectIds)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the projects.')); toastService.add('error', gettext('Unable to delete the projects.'));
}); });
}; };
this.getProject = function(project_id) { this.getProject = function(projectId) {
return apiService.get('/api/keystone/projects/' + project_id) return apiService.get('/api/keystone/projects/' + projectId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the project.')); toastService.add('error', gettext('Unable to retrieve the project.'));
}); });
@ -222,23 +230,23 @@ limitations under the License.
}); });
}; };
this.deleteProject = function(project_id) { this.deleteProject = function(projectId) {
return apiService.delete('/api/keystone/projects/' + project_id) return apiService.delete('/api/keystone/projects/' + projectId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to delete the project.')); toastService.add('error', gettext('Unable to delete the project.'));
}); });
}; };
this.grantRole = function(project_id, role_id, user_id) { this.grantRole = function(projectId, roleId, userId) {
return apiService.put('/api/keystone/projects/' + project_id + '/' + return apiService.put('/api/keystone/projects/' + projectId + '/' +
role_id + '/' + user_id) roleId + '/' + userId)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to grant the role.')); toastService.add('error', gettext('Unable to grant the role.'));
}); });
}; };
/** /**
* @name hz.api.keyStoneAPI.serviceCatalog * @name horizon.openstack-service-api.keystone.serviceCatalog
* @description * @description
* Returns the service catalog. * Returns the service catalog.
* @param {Object} config * @param {Object} config
@ -252,12 +260,9 @@ limitations under the License.
}; };
} }
angular.module('hz.api') /**
.service('hz.api.keystone', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', KeystoneAPI]);
/**
* @ngdoc service * @ngdoc service
* @name hz.api.userSession * @name horizon.openstack-service-api.userSession
* @description * @description
* Provides cached access to the user session. The cache may be reset * Provides cached access to the user session. The cache may be reset
* at any time by accessing the cache and calling removeAll, which means * at any time by accessing the cache and calling removeAll, which means
@ -276,11 +281,17 @@ limitations under the License.
* and used transparently where needed without making every single use of it * and used transparently where needed without making every single use of it
* pass it through as an argument. * pass it through as an argument.
*/ */
angular
.module('horizon.openstack-service-api')
.factory('horizon.openstack-service-api.userSession', userSession);
userSession.$inject = ['$cacheFactory', 'horizon.openstack-service-api.keystone'];
function userSession($cacheFactory, keystoneAPI) { function userSession($cacheFactory, keystoneAPI) {
var service = {}; var service = {};
service.cache = $cacheFactory('hz.api.userSession', {capacity: 1}); service.cache = $cacheFactory('horizon.openstack-service-api.userSession', {capacity: 1});
service.get = function () { service.get = function () {
return keystoneAPI.getCurrentUserSession({cache: service.cache}) return keystoneAPI.getCurrentUserSession({cache: service.cache})
@ -293,12 +304,9 @@ limitations under the License.
return service; return service;
} }
angular.module('hz.api')
.factory('hz.api.userSession', ['$cacheFactory', 'hz.api.keystone', userSession]);
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.serviceCatalog * @name horizon.openstack-service-api.serviceCatalog
* @description * @description
* Provides cached access to the Service Catalog with utilities to help * Provides cached access to the Service Catalog with utilities to help
* with asynchronous data loading. The cache may be reset at any time * with asynchronous data loading. The cache may be reset at any time
@ -316,13 +324,22 @@ limitations under the License.
* and used transparently where needed without making every single use of it * and used transparently where needed without making every single use of it
* pass it through as an argument. * pass it through as an argument.
*/ */
angular
.module('horizon.openstack-service-api')
.factory('horizon.openstack-service-api.serviceCatalog', serviceCatalog);
serviceCatalog.$inject = ['$cacheFactory',
'$q',
'horizon.openstack-service-api.keystone',
'horizon.openstack-service-api.userSession'];
function serviceCatalog($cacheFactory, $q, keystoneAPI, userSession) { function serviceCatalog($cacheFactory, $q, keystoneAPI, userSession) {
var service = {}; var service = {};
service.cache = $cacheFactory('hz.api.serviceCatalog', {capacity: 1}); service.cache = $cacheFactory('horizon.openstack-service-api.serviceCatalog', {capacity: 1});
/** /**
* @name hz.api.serviceCatalog.get * @name horizon.openstack-service-api.serviceCatalog.get
* @description * @description
* Returns the service catalog. This is cached. * Returns the service catalog. This is cached.
* *
@ -335,14 +352,14 @@ limitations under the License.
*/ */
service.get = function() { service.get = function() {
return keystoneAPI.serviceCatalog({cache: service.cache}) return keystoneAPI.serviceCatalog({cache: service.cache})
.then(function(response){ .then(function(response) {
return response.data; return response.data;
} }
); );
}; };
/** /**
* @name hz.api.serviceCatalog.ifTypeEnabled * @name horizon.openstack-service-api.serviceCatalog.ifTypeEnabled
* @description * @description
* Checks if the desired service is enabled. If it is enabled, use the * Checks if the desired service is enabled. If it is enabled, use the
* promise returned to execute the desired function. If it is not enabled, * promise returned to execute the desired function. If it is not enabled,
@ -426,12 +443,4 @@ limitations under the License.
return service; return service;
} }
angular.module('hz.api')
.factory('hz.api.serviceCatalog', ['$cacheFactory',
'$q',
'hz.api.keystone',
'hz.api.userSession',
serviceCatalog]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.keystone', function(keystoneAPI) { beforeEach(inject(['horizon.openstack-service-api.keystone', function(keystoneAPI) {
service = keystoneAPI; service = keystoneAPI;
}])); }]));
@ -42,7 +42,7 @@
"method": "get", "method": "get",
"path": "/api/keystone/users/", "path": "/api/keystone/users/",
"data": {}, "data": {},
"error": "Unable to retrieve users." "error": "Unable to retrieve the users."
}, },
{ {
"func": "getUsers", "func": "getUsers",
@ -53,7 +53,7 @@
"info": true "info": true
} }
}, },
"error": "Unable to retrieve users.", "error": "Unable to retrieve the users.",
"testInput": [ "testInput": [
{ {
"info": true "info": true
@ -385,15 +385,15 @@
describe("userSession", function() { describe("userSession", function() {
var factory, keystoneAPI; var factory, keystoneAPI;
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
keystoneAPI = {getCurrentUserSession: angular.noop}; keystoneAPI = {getCurrentUserSession: angular.noop};
$provide.value('hz.api.keystone', keystoneAPI); $provide.value('horizon.openstack-service-api.keystone', keystoneAPI);
$provide.value('$cacheFactory', function() { return 'cache'; }); $provide.value('$cacheFactory', function() { return 'cache'; });
})); }));
beforeEach(inject(['hz.api.userSession', function(userSession) { beforeEach(inject(['horizon.openstack-service-api.userSession', function(userSession) {
factory = userSession; factory = userSession;
}])); }]));
@ -433,13 +433,13 @@
describe("serviceCatalog", function() { describe("serviceCatalog", function() {
var factory, q, keystoneAPI, userSession, deferred; var factory, q, keystoneAPI, userSession, deferred;
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
keystoneAPI = {serviceCatalog: angular.noop}; keystoneAPI = {serviceCatalog: angular.noop};
$provide.value('hz.api.keystone', keystoneAPI); $provide.value('horizon.openstack-service-api.keystone', keystoneAPI);
userSession = {get: angular.noop}; userSession = {get: angular.noop};
$provide.value('hz.api.userSession', userSession); $provide.value('horizon.openstack-service-api.userSession', userSession);
deferred = {promise: angular.noop, reject: angular.noop, resolve: angular.noop}; deferred = {promise: angular.noop, reject: angular.noop, resolve: angular.noop};
q = {all: function() {return {then: angular.noop};}, q = {all: function() {return {then: angular.noop};},
defer: function() { return deferred;}}; defer: function() { return deferred;}};
@ -447,7 +447,7 @@
$provide.value('$cacheFactory', function() { return 'cache'; }); $provide.value('$cacheFactory', function() { return 'cache'; });
})); }));
beforeEach(inject(['hz.api.serviceCatalog', function(serviceCatalog) { beforeEach(inject(['horizon.openstack-service-api.serviceCatalog', function(serviceCatalog) {
factory = serviceCatalog; factory = serviceCatalog;
}])); }]));

View File

@ -0,0 +1,204 @@
/**
* 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.
*/
(function () {
'use strict';
angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.neutron', NeutronAPI);
NeutronAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/**
* @ngdoc service
* @name horizon.openstack-service-api.neutron
* @description Provides access to Neutron APIs.
*/
function NeutronAPI(apiService, toastService) {
// Networks
/**
* @name horizon.openstack-service-api.neturonAPI.getNetworks
* @description
* Get a list of networks for a tenant.
*
* The listing result is an object with property "items". Each item is
* a network.
*/
this.getNetworks = function() {
return apiService.get('/api/neutron/networks/')
.error(function () {
toastService.add('error', gettext('Unable to retrieve the networks.'));
});
};
/**
* @name horizon.openstack-service-api.neutron.createNetwork
* @description
* Create a new network.
* @returns The new network object on success.
*
* @param {Object} newNetwork
* The network to create. Required.
*
* Example new network object
* {
* "name": "myNewNetwork",
* "admin_state_up": true,
* "net_profile_id" : "asdsarafssdaser",
* "shared": true,
* "tenant_id": "4fd44f30292945e481c7b8a0c8908869
* }
*
* Description of properties on the network object
*
* @property {string} newNetwork.name
* The name of the new network. Optional.
*
* @property {boolean} newNetwork.admin_state_up
* The administrative state of the network, which is up (true) or
* down (false). Optional.
*
* @property {string} newNetwork.net_profile_id
* The network profile id. Optional.
*
* @property {boolean} newNetwork.shared
* Indicates whether this network is shared across all tenants.
* By default, only adminstative users can change this value. Optional.
*
* @property {string} newNetwork.tenant_id
* The UUID of the tenant that will own the network. This tenant can
* be different from the tenant that makes the create network request.
* However, only administative users can specify a tenant ID other than
* their own. You cannot change this value through authorization
* policies. Optional.
*
*/
this.createNetwork = function(newNetwork) {
return apiService.post('/api/neutron/networks/', newNetwork)
.error(function () {
toastService.add('error', gettext('Unable to create the network.'));
});
};
// Subnets
/**
* @name horizon.openstack-service-api.neutron.getSubnets
* @description
* Get a list of subnets for a network.
*
* The listing result is an object with property "items". Each item is
* a subnet.
*
* @param {string} networkId
* The network id to retrieve subnets for. Required.
*/
this.getSubnets = function(networkId) {
return apiService.get('/api/neutron/subnets/', networkId)
.error(function () {
toastService.add('error', gettext('Unable to retrieve the subnets.'));
});
};
/**
* @name horizon.openstack-service-api.neutron.createSubnet
* @description
* Create a Subnet for given Network.
* @returns The JSON representation of Subnet on success.
*
* @param {Object} newSubnet
* The subnet to create.
*
* Example new subnet object
* {
* "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
* "ip_version": 4,
* "cidr": "192.168.199.0/24",
* "name": "mySubnet",
* "tenant_id": "4fd44f30292945e481c7b8a0c8908869,
* "allocation_pools": [
* {
* "start": "192.168.199.2",
* "end": "192.168.199.254"
* }
* ],
* "gateway_ip": "192.168.199.1",
* "id": "abce",
* "enable_dhcp": true,
* }
*
* Description of properties on the subnet object
* @property {string} newSubnet.network_id
* The id of the attached network. Required.
*
* @property {number} newSubnet.ip_version
* The IP version, which is 4 or 6. Required.
*
* @property {string} newSubnet.cidr
* The CIDR. Required.
*
* @property {string} newSubnet.name
* The name of the new subnet. Optional.
*
* @property {string} newSubnet.tenant_id
* The ID of the tenant who owns the network. Only administrative users
* can specify a tenant ID other than their own. Optional.
*
* @property {string|Array} newSubnet.allocation_pools
* The start and end addresses for the allocation pools. Optional.
*
* @property {string} newSubnet.gateway_ip
* The gateway IP address. Optional.
*
* @property {string} newSubnet.id
* The ID of the subnet. Optional.
*
* @property {boolean} newSubnet.enable_dhcp
* Set to true if DHCP is enabled and false if DHCP is disabled. Optional.
*
*/
this.createSubnet = function(newSubnet) {
return apiService.post('/api/neutron/subnets/', newSubnet)
.error(function () {
toastService.add('error', gettext('Unable to create the subnet.'));
});
};
// Ports
/**
* @name horizon.openstack-service-api.neutron.getPorts
* @description
* Get a list of ports for a network.
*
* The listing result is an object with property "items". Each item is
* a port.
*
* @param {string} networkId
* The network id to retrieve ports for. Required.
*/
this.getPorts = function(networkId) {
return apiService.get('/api/neutron/ports/', networkId)
.error(function () {
toastService.add('error', gettext('Unable to retrieve the ports.'));
});
};
}
}());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.neutron', function(neutronAPI) { beforeEach(inject(['horizon.openstack-service-api.neutron', function(neutronAPI) {
service = neutronAPI; service = neutronAPI;
}])); }]));

View File

@ -16,23 +16,30 @@ limitations under the License.
(function () { (function () {
'use strict'; 'use strict';
/** angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.nova', NovaAPI);
NovaAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/**
* @ngdoc service * @ngdoc service
* @name hz.api.novaAPI * @name horizon.openstack-service-api.nova
* @description Provides access to Nova APIs. * @description Provides access to Nova APIs.
*/ */
function NovaAPI(apiService, toastService) { function NovaAPI(apiService, toastService) {
// Keypairs // Keypairs
/** /**
* @name hz.api.novaAPI.getKeypairs * @name horizon.openstack-service-api.nova.getKeypairs
* @description * @description
* Get a list of keypairs. * Get a list of keypairs.
* *
* The listing result is an object with property "items". Each item is * The listing result is an object with property "items". Each item is
* a keypair. * a keypair.
*/ */
this.getKeypairs = function() { this.getKeypairs = function() {
return apiService.get('/api/nova/keypairs/') return apiService.get('/api/nova/keypairs/')
.error(function () { .error(function () {
@ -40,20 +47,20 @@ limitations under the License.
}); });
}; };
/** /**
* @name hz.api.novaAPI.createKeypair * @name horizon.openstack-service-api.nova.createKeypair
* @description * @description
* Create a new keypair. This returns the new keypair object on success. * Create a new keypair. This returns the new keypair object on success.
* *
* @param {Object} newKeypair * @param {Object} newKeypair
* The keypair to create. * The keypair to create.
* *
* @param {string} newKeypair.name * @param {string} newKeypair.name
* The name of the new keypair. Required. * The name of the new keypair. Required.
* *
* @param {string} newKeypair.public_key * @param {string} newKeypair.public_key
* The public key. Optional. * The public key. Optional.
*/ */
this.createKeypair = function(newKeypair) { this.createKeypair = function(newKeypair) {
return apiService.post('/api/nova/keypairs/', newKeypair) return apiService.post('/api/nova/keypairs/', newKeypair)
.error(function () { .error(function () {
@ -67,14 +74,14 @@ limitations under the License.
// Availability Zones // Availability Zones
/** /**
* @name hz.api.novaAPI.getAvailabilityZones * @name horizon.openstack-service-api.nova.getAvailabilityZones
* @description * @description
* Get a list of Availability Zones. * Get a list of Availability Zones.
* *
* The listing result is an object with property "items". Each item is * The listing result is an object with property "items". Each item is
* an availability zone. * an availability zone.
*/ */
this.getAvailabilityZones = function() { this.getAvailabilityZones = function() {
return apiService.get('/api/nova/availzones/') return apiService.get('/api/nova/availzones/')
.error(function () { .error(function () {
@ -86,7 +93,7 @@ limitations under the License.
// Limits // Limits
/** /**
* @name hz.api.novaAPI.getLimits * @name horizon.openstack-service-api.nova.getLimits
* @description * @description
* Returns current limits. * Returns current limits.
* *
@ -124,7 +131,7 @@ limitations under the License.
// Servers // Servers
/** /**
* @name hz.api.novaAPI.createServer * @name horizon.openstack-service-api.nova.createServer
* @description * @description
* Create a server using the parameters supplied in the * Create a server using the parameters supplied in the
* newServer. The required parameters: * newServer. The required parameters:
@ -149,7 +156,7 @@ limitations under the License.
}; };
/** /**
* @name hz.api.novaAPI.getServer * @name horizon.openstack-service-api.nova.getServer
* @description * @description
* Get a single server by ID * Get a single server by ID
* @param {string} id * @param {string} id
@ -159,11 +166,11 @@ limitations under the License.
return apiService.get('/api/nova/servers/' + id) return apiService.get('/api/nova/servers/' + id)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the server.')); toastService.add('error', gettext('Unable to retrieve the server.'));
}); });
}; };
/** /**
* @name hz.api.novaAPI.getExtensions * @name horizon.openstack-service-api.nova.getExtensions
* @description * @description
* Returns a list of enabled extensions. * Returns a list of enabled extensions.
* *
@ -193,7 +200,7 @@ limitations under the License.
}; };
/** /**
* @name hz.api.novaAPI.getFlavors * @name horizon.openstack-service-api.nova.getFlavors
* @description * @description
* Returns a list of flavors. * Returns a list of flavors.
* *
@ -238,7 +245,7 @@ limitations under the License.
}; };
/** /**
* @name hz.api.novaAPI.getFlavor * @name horizon.openstack-service-api.nova.getFlavor
* @description * @description
* Get a single flavor by ID. * Get a single flavor by ID.
* @param {string} id * @param {string} id
@ -252,11 +259,11 @@ limitations under the License.
return apiService.get('/api/nova/flavors/' + id, config) return apiService.get('/api/nova/flavors/' + id, config)
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the flavor.')); toastService.add('error', gettext('Unable to retrieve the flavor.'));
}); });
}; };
/** /**
* @name hz.api.novaAPI.getFlavorExtraSpecs * @name horizon.openstack-service-api.nova.getFlavorExtraSpecs
* @description * @description
* Get a single flavor's extra specs by ID. * Get a single flavor's extra specs by ID.
* @param {string} id * @param {string} id
@ -266,38 +273,43 @@ limitations under the License.
return apiService.get('/api/nova/flavors/' + id + '/extra-specs') return apiService.get('/api/nova/flavors/' + id + '/extra-specs')
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the flavor extra specs.')); toastService.add('error', gettext('Unable to retrieve the flavor extra specs.'));
}); });
}; };
} }
angular.module('hz.api') /**
.service('hz.api.nova', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', NovaAPI]); * @ngdoc service
* @name horizon.openstack-service-api.novaExtensions
* @description
* Provides cached access to Nova Extensions with utilities to help
* with asynchronous data loading. The cache may be reset at any time
* by accessing the cache and calling removeAll. The next call to any
* function will retrieve fresh results.
*
* The enabled extensions do not change often, so using cached data will
* speed up results. Even on a local devstack in informal testing,
* this saved between 30 - 100 ms per request.
*/
angular
.module('horizon.openstack-service-api')
.factory('horizon.openstack-service-api.novaExtensions', NovaExtensionsAPI);
/** NovaExtensionsAPI.$inject = ['$cacheFactory',
* @ngdoc service '$q',
* @name hz.api.novaExtensions 'horizon.openstack-service-api.nova'];
* @description
* Provides cached access to Nova Extensions with utilities to help
* with asynchronous data loading. The cache may be reset at any time
* by accessing the cache and calling removeAll. The next call to any
* function will retrieve fresh results.
*
* The enabled extensions do not change often, so using cached data will
* speed up results. Even on a local devstack in informal testing,
* this saved between 30 - 100 ms per request.
*/
function NovaExtensions($cacheFactory, $q, novaAPI) {
var service = {};
service.cache = $cacheFactory('hz.api.novaExtensions', {capacity: 1});
service.get = function () { function NovaExtensionsAPI($cacheFactory, $q, novaAPI) {
return novaAPI.getExtensions({cache: service.cache}) var service = {};
.then(function (data) { service.cache = $cacheFactory('horizon.openstack-service-api.novaExtensions', {capacity: 1});
return data.data.items;
});
};
service.ifNameEnabled = function(desired) { service.get = function () {
return novaAPI.getExtensions({cache: service.cache})
.then(function (data) {
return data.data.items;
});
};
service.ifNameEnabled = function(desired) {
var deferred = $q.defer(); var deferred = $q.defer();
service.get().then(onDataLoaded, onDataFailure); service.get().then(onDataLoaded, onDataFailure);
@ -307,14 +319,14 @@ limitations under the License.
deferred.resolve(); deferred.resolve();
} else { } else {
deferred.reject(interpolate( deferred.reject(interpolate(
gettext('Extension is not enabled: %(extension)s'), gettext('Extension is not enabled: %(extension)s.'),
{extension: desired}, {extension: desired},
true)); true));
} }
} }
function onDataFailure() { function onDataFailure() {
deferred.reject(gettext('Cannot get Nova extension list.')); deferred.reject(gettext('Cannot get the Nova extension list.'));
} }
return deferred.promise; return deferred.promise;
@ -324,7 +336,7 @@ limitations under the License.
service.ifEnabled = service.ifNameEnabled; service.ifEnabled = service.ifNameEnabled;
function enabled(resources, key, desired) { function enabled(resources, key, desired) {
if(resources) { if (resources) {
return resources.some(function (resource) { return resources.some(function (resource) {
return resource[key] === desired; return resource[key] === desired;
}); });
@ -335,11 +347,4 @@ limitations under the License.
return service; return service;
} }
angular.module('hz.api')
.factory('hz.api.novaExtensions', ['$cacheFactory',
'$q',
'hz.api.nova',
NovaExtensions]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.nova', function(novaAPI) { beforeEach(inject(['horizon.openstack-service-api.nova', function(novaAPI) {
service = novaAPI; service = novaAPI;
}])); }]));
@ -247,18 +247,18 @@
describe("novaExtensions", function() { describe("novaExtensions", function() {
var factory, q, novaAPI; var factory, q, novaAPI;
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
novaAPI = {getExtensions: function() {return {then: angular.noop};}}; novaAPI = {getExtensions: function() {return {then: angular.noop};}};
q = {defer: function() { return {resolve: angular.noop}; }}; q = {defer: function() { return {resolve: angular.noop}; }};
$provide.value('$cacheFactory', function() {return "cache";}); $provide.value('$cacheFactory', function() {return "cache";});
$provide.value('$q', q); $provide.value('$q', q);
$provide.value('hz.api.nova', novaAPI); $provide.value('horizon.openstack-service-api.nova', novaAPI);
})); }));
beforeEach(inject(function($injector) { beforeEach(inject(function($injector) {
factory = $injector.get('hz.api.novaExtensions'); factory = $injector.get('horizon.openstack-service-api.novaExtensions');
})); }));
it("is defined", function() { it("is defined", function() {
@ -304,7 +304,7 @@
deferred.reject.calls.reset(); deferred.reject.calls.reset();
func2(); func2();
expect(deferred.reject).toHaveBeenCalledWith('Cannot get Nova extension list.'); expect(deferred.reject).toHaveBeenCalledWith('Cannot get the Nova extension list.');
}); });
it("defines .ifEnabled", function() { it("defines .ifEnabled", function() {

View File

@ -13,8 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/*global angular*/
(function () { (function () {
'use strict'; 'use strict';
angular.module('hz.api', ['hz.api.common']);
}()); angular
.module('horizon.openstack-service-api', []);
}());

View File

@ -14,16 +14,23 @@ limitations under the License.
(function() { (function() {
'use strict'; 'use strict';
angular
.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.policy', PolicyService);
PolicyService.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.policyAPI * @name horizon.openstack-service-api.policy
* @description Provides a direct pass through to the policy engine in * @description Provides a direct pass through to the policy engine in
* Horizon. * Horizon.
*/ */
function PolicyService(apiService, toastService) { function PolicyService(apiService, toastService) {
/** /**
* @name hz.api.policyAPI.check * @name horizon.openstack-service-api.policy.check
* @description * @description
* Check the passed in policy rule list to determine if the user has * Check the passed in policy rule list to determine if the user has
* permission to perform the actions specified by the rules. The service * permission to perform the actions specified by the rules. The service
@ -59,14 +66,11 @@ limitations under the License.
* "allowed": false * "allowed": false
* } * }
*/ */
this.check = function (policy_rules) { this.check = function (policyRules) {
return apiService.post('/api/policy/', policy_rules) return apiService.post('/api/policy/', policyRules)
.error(function() { .error(function() {
toastService.add('warning', gettext('Policy check failed.')); toastService.add('warning', gettext('Policy check failed.'));
}); });
}; };
} }
angular.module('hz.api')
.service('hz.api.policy', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', PolicyService]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.policy', function(policyAPI) { beforeEach(inject(['horizon.openstack-service-api.policy', function(policyAPI) {
service = policyAPI; service = policyAPI;
}])); }]));

View File

@ -16,15 +16,21 @@ limitations under the License.
(function () { (function () {
'use strict'; 'use strict';
angular.module('horizon.openstack-service-api')
.service('horizon.openstack-service-api.security-group', SecurityGroupAPI);
SecurityGroupAPI.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.SecurityGroup * @name horizon.openstack-service-api.security-group
* @description Provides access to Security Groups * @description Provides access to Security Groups
*/ */
function SecurityGroup(apiService, toastService) { function SecurityGroupAPI(apiService, toastService) {
/** /**
* @name hz.api.SecurityGroup.list * @name horizon.openstack-service-api.security-group.list
* @description * @description
* Get a list of security groups. * Get a list of security groups.
* *
@ -62,14 +68,7 @@ limitations under the License.
return apiService.get('/api/network/securitygroups/') return apiService.get('/api/network/securitygroups/')
.error(function () { .error(function () {
toastService.add('error', gettext('Unable to retrieve the security groups.')); toastService.add('error', gettext('Unable to retrieve the security groups.'));
}); });
}; };
} }
// Register it with the API module so that anybody using the
// API module will have access to the Security Group APIs.
angular.module('hz.api')
.service('hz.api.security-group', ['hz.api.common.service', 'horizon.framework.widgets.toast.service', SecurityGroup]);
}()); }());

View File

@ -22,13 +22,13 @@
var apiService = {}; var apiService = {};
var toastService = {}; var toastService = {};
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
window.apiTest.initServices($provide, apiService, toastService); window.apiTest.initServices($provide, apiService, toastService);
})); }));
beforeEach(inject(['hz.api.security-group', function(securityGroup) { beforeEach(inject(['horizon.openstack-service-api.security-group', function(securityGroup) {
service = securityGroup; service = securityGroup;
}])); }]));

View File

@ -17,9 +17,15 @@
(function () { (function () {
'use strict'; 'use strict';
angular
.module('horizon.openstack-service-api')
.factory('horizon.openstack-service-api.settings', settingsService);
settingsService.$inject = ['$q', 'horizon.framework.util.http.service'];
/** /**
* @ngdoc service * @ngdoc service
* @name hz.api.settingsService * @name horizon.openstack-service-api.settings
* @description * @description
* Provides utilities to the cached settings data. This helps * Provides utilities to the cached settings data. This helps
* with asynchronous data loading. * with asynchronous data loading.
@ -39,43 +45,43 @@
var service = {}; var service = {};
/** /**
* @name hz.api.configAPI.getSettings * @name horizon.openstack-service-api.config.getSettings
* @description * @description
* Gets all the allowed settings * Gets all the allowed settings
* *
* Returns an object with settings. * Returns an object with settings.
*/ */
service.getSettings = function (suppressError) { service.getSettings = function (suppressError) {
function onError() { function onError() {
var message = gettext('Unable to retrieve settings.'); var message = gettext('Unable to retrieve settings.');
if (!suppressError && horizon.alert) { if (!suppressError && horizon.alert) {
horizon.alert('error', message); horizon.alert('error', message);
} }
return message; return message;
} }
// The below ensures that errors are handled like other // The below ensures that errors are handled like other
// service errors (for better or worse), but when successful // service errors (for better or worse), but when successful
// unwraps the success result data for direct consumption. // unwraps the success result data for direct consumption.
return apiService.get('/api/settings/', {cache: true}) return apiService.get('/api/settings/', {cache: true})
.error(onError) .error(onError)
.then(function (response) { .then(function (response) {
return response.data; return response.data;
}); });
}; };
/** /**
* @name hz.api.settingsService.getSetting * @name horizon.openstack-service-api.settings.getSetting
* @description * @description
* This retrieves a specific setting. * This retrieves a specific setting.
* *
* If the setting isn't found, it will return undefined unless a default * If the setting isn't found, it will return undefined unless a default
* is specified. In that case, the default will be returned. * is specified. In that case, the default will be returned.
* *
* @param {string} setting The path to the setting to get. * @param {string} path The path to the setting to get.
* *
* local_settings.py allows you to create settings such as: * local_settings.py allows you to create settings such as:
* *
@ -91,7 +97,7 @@
* OPENSTACK_HYPERVISOR_FEATURES.can_set_mount_point * OPENSTACK_HYPERVISOR_FEATURES.can_set_mount_point
* OPENSTACK_HYPERVISOR_FEATURES.can_set_password * OPENSTACK_HYPERVISOR_FEATURES.can_set_password
* *
* @param {object=} defaultSetting If the requested setting does not exist, * @param {Object} defaultSetting If the requested setting does not exist,
* the defaultSetting will be returned. This is optional. * the defaultSetting will be returned. This is optional.
* *
* @example * @example
@ -105,9 +111,9 @@
``` ```
*/ */
service.getSetting = function (path, defaultSetting) { service.getSetting = function (path, defaultSetting) {
var deferred = $q.defer(), var deferred = $q.defer();
pathElements = path.split("."), var pathElements = path.split(".");
settingAtRequestedPath; var settingAtRequestedPath;
function onSettingsLoaded(settings) { function onSettingsLoaded(settings) {
// This recursively traverses the object hierarchy until either all the // This recursively traverses the object hierarchy until either all the
@ -137,7 +143,7 @@
}; };
/** /**
* @name hz.api.settingsService.ifEnabled * @name horizon.openstack-service-api.settings.ifEnabled
* @description * @description
* Checks if the desired setting is enabled. This returns a promise. * Checks if the desired setting is enabled. This returns a promise.
* If the setting is enabled, the promise will be resolved. * If the setting is enabled, the promise will be resolved.
@ -159,12 +165,12 @@
* OPENSTACK_HYPERVISOR_FEATURES.can_set_mount_point * OPENSTACK_HYPERVISOR_FEATURES.can_set_mount_point
* OPENSTACK_HYPERVISOR_FEATURES.can_set_password * OPENSTACK_HYPERVISOR_FEATURES.can_set_password
* *
* @param (object=} expected Used to determine if the setting is * @param {Object} [expected=true] Used to determine if the setting is
* enabled. The actual setting will be evaluated against the expected * enabled. The actual setting will be evaluated against the expected
* value using angular.equals(). If they are equal, then it will be * value using angular.equals(). If they are equal, then it will be
* considered enabled. This is optional and defaults to True. * considered enabled. This is optional and defaults to True.
* *
* @param {object=} defaultSetting If the requested setting does not exist, * @param {Object} [defaultSetting=true] If the requested setting does not exist,
* the defaultSetting will be used for evaluation. This is optional. If * the defaultSetting will be used for evaluation. This is optional. If
* not specified and the setting is not specified, then the setting will * not specified and the setting is not specified, then the setting will
* not be considered to be enabled. * not be considered to be enabled.
@ -253,8 +259,4 @@
return service; return service;
} }
angular.module('hz.api')
.factory('hz.api.settingsService', ['$q', 'hz.api.common.service', settingsService]);
}()); }());

View File

@ -32,13 +32,14 @@
return responseMockOpts.succeed ? [200, testData, {}] : [500, 'Fail', {}]; return responseMockOpts.succeed ? [200, testData, {}] : [500, 'Fail', {}];
} }
describe('settingsService', function () { describe('horizon.openstack-service-api.settings', function () {
var settingsService; var settingsService;
beforeEach(module('hz.api')); beforeEach(module('horizon.openstack-service-api'));
beforeEach(module('horizon.framework.util.http'));
beforeEach(inject(function (_$httpBackend_, $injector) { beforeEach(inject(function (_$httpBackend_, $injector) {
responseMockOpts.succeed = true; responseMockOpts.succeed = true;
settingsService = $injector.get('hz.api.settingsService'); settingsService = $injector.get('horizon.openstack-service-api.settings');
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
$httpBackend.whenGET('/api/settings/').respond(responseMockReturn); $httpBackend.whenGET('/api/settings/').respond(responseMockReturn);
$httpBackend.expectGET('/api/settings/'); $httpBackend.expectGET('/api/settings/');

View File

@ -19,16 +19,15 @@
<script src="{{ STATIC_URL }}auth/login/login.controller.js"></script> <script src="{{ STATIC_URL }}auth/login/login.controller.js"></script>
<script src="{{ STATIC_URL }}auth/login/login-finder.directive.js"></script> <script src="{{ STATIC_URL }}auth/login/login-finder.directive.js"></script>
<script src='{{ STATIC_URL }}horizon/js/angular/hz.api.module.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/openstack-service-api.module.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.cinder.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/cinder.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.common.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/glance.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.config.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/keystone.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.glance.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/neutron.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.keystone.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/nova.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.neutron.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/policy.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.nova.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/security-group.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.policy.js'></script> <script src='{{ STATIC_URL }}openstack-service-api/settings.service.js'></script>
<script src='{{ STATIC_URL }}horizon/js/angular/services/hz.api.security-group.js'></script>
<script src="{{ STATIC_URL }}horizon/lib/d3.js"></script> <script src="{{ STATIC_URL }}horizon/lib/d3.js"></script>
@ -39,6 +38,7 @@
<script src='{{ STATIC_URL }}framework/util/util.module.js'></script> <script src='{{ STATIC_URL }}framework/util/util.module.js'></script>
<script src='{{ STATIC_URL }}framework/util/bind-scope/bind-scope.js'></script> <script src='{{ STATIC_URL }}framework/util/bind-scope/bind-scope.js'></script>
<script src='{{ STATIC_URL }}framework/util/filters/filters.js'></script> <script src='{{ STATIC_URL }}framework/util/filters/filters.js'></script>
<script src='{{ STATIC_URL }}framework/util/http/http.js'></script>
<script src='{{ STATIC_URL }}framework/util/i18n/i18n.js'></script> <script src='{{ STATIC_URL }}framework/util/i18n/i18n.js'></script>
<script src='{{ STATIC_URL }}framework/util/validators/validators.js'></script> <script src='{{ STATIC_URL }}framework/util/validators/validators.js'></script>
<script src='{{ STATIC_URL }}framework/util/workflow/workflow.js'></script> <script src='{{ STATIC_URL }}framework/util/workflow/workflow.js'></script>