Add angular Load Balancers V2 panel
This adds an angular version of the Load Balancers V2 panel, including the Load Balancers table and config to get karma working. The karma config assumes the horizon directory is a sibling of neutron-lbaas-dashboard. To use, copy the _1481_project_ng_loadbalancersv2_panel.py file from neutron_lbaas_dashboard/enabled into openstack_dashboard/enabled. Partially-Implements: blueprint horizon-lbaas-v2-ui Change-Id: I99c4ec705433385c19256c887944706472642a25
This commit is contained in:
parent
2d5f4a29ae
commit
75fc881f7f
2
.gitignore
vendored
2
.gitignore
vendored
@ -28,6 +28,8 @@ pip-log.txt
|
||||
nosetests.xml
|
||||
.testrepository
|
||||
.venv
|
||||
node_modules
|
||||
coverage*
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
@ -14,6 +12,9 @@
|
||||
|
||||
import pbr.version
|
||||
|
||||
# Register the REST API URLs so they can be called from the JavaScript files
|
||||
import neutron_lbaas_dashboard.api.rest # noqa
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo(
|
||||
'neutron_lbaas_dashboard').version_string()
|
||||
|
25
neutron_lbaas_dashboard/api/rest/__init__.py
Normal file
25
neutron_lbaas_dashboard/api/rest/__init__.py
Normal file
@ -0,0 +1,25 @@
|
||||
# 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.
|
||||
"""This package holds the REST API that supports the LBaaS v2 dashboard
|
||||
Javascript code.
|
||||
|
||||
It is not intended to be used outside of Horizon, and makes no promises of
|
||||
stability or fitness for purpose outside of that scope.
|
||||
|
||||
It does not promise to adhere to the general OpenStack API Guidelines set out
|
||||
in https://wiki.openstack.org/wiki/APIChangeGuidelines.
|
||||
"""
|
||||
|
||||
# import REST API modules here
|
||||
from neutron_lbaas_dashboard.api.rest import lbaasv2 # noqa
|
41
neutron_lbaas_dashboard/api/rest/lbaasv2.py
Normal file
41
neutron_lbaas_dashboard/api/rest/lbaasv2.py
Normal file
@ -0,0 +1,41 @@
|
||||
# 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.
|
||||
"""API over the neutron LBaaS v2 service.
|
||||
"""
|
||||
|
||||
from django.views import generic
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
from openstack_dashboard.api.rest import urls
|
||||
from openstack_dashboard.api.rest import utils as rest_utils
|
||||
|
||||
neutronclient = neutron.neutronclient
|
||||
|
||||
|
||||
@urls.register
|
||||
class LoadBalancers(generic.View):
|
||||
"""API for load balancers.
|
||||
|
||||
"""
|
||||
url_regex = r'lbaas/loadbalancers/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""List load balancers for current project.
|
||||
|
||||
The listing result is an object with property "items".
|
||||
"""
|
||||
tenant_id = request.user.project_id
|
||||
result = neutronclient(request).list_loadbalancers(tenant_id=tenant_id)
|
||||
return {'items': result.get('loadbalancers')}
|
@ -0,0 +1,42 @@
|
||||
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
|
||||
class NGLoadBalancers(horizon.Panel):
|
||||
name = _("Load Balancers")
|
||||
slug = 'ngloadbalancersv2'
|
||||
permissions = ('openstack.services.network',)
|
||||
|
||||
def allowed(self, context):
|
||||
# TODO(jpomero) temporarily enabling panel for any user
|
||||
# request = context['request']
|
||||
# if not request.user.has_perms(self.permissions):
|
||||
# return False
|
||||
# try:
|
||||
# if not neutron.is_service_enabled(request,
|
||||
# config_name='enable_lb',
|
||||
# ext_name='lbaas'):
|
||||
# return False
|
||||
# except Exception:
|
||||
# LOG.error("Call to list enabled services failed. This is likely "
|
||||
# "due to a problem communicating with the Neutron "
|
||||
# "endpoint. Load Balancers panel will not be displayed")
|
||||
# return False
|
||||
# if not super(LoadBalancer, self).allowed(context):
|
||||
# return False
|
||||
return True
|
@ -0,0 +1,11 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Load Balancers" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
<hz-page-header header="'{% trans "Load Balancers" %}'"></hz-page-header>
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
<ng-include src="'{{ STATIC_URL }}dashboard/project/lbaasv2/loadbalancers/table.html'"></ng-include>
|
||||
{% endblock %}
|
@ -0,0 +1,24 @@
|
||||
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf.urls import patterns
|
||||
from django.conf.urls import url
|
||||
|
||||
from neutron_lbaas_dashboard.dashboards.project.ngloadbalancersv2 import views
|
||||
|
||||
|
||||
urlpatterns = patterns(
|
||||
'neutron_lbaas_dashboard.dashboards.project.ngloadbalancersv2.views',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
)
|
@ -0,0 +1,19 @@
|
||||
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.views import generic
|
||||
|
||||
|
||||
class IndexView(generic.TemplateView):
|
||||
template_name = 'project/ngloadbalancersv2/index.html'
|
@ -0,0 +1,51 @@
|
||||
# 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.
|
||||
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'ngloadbalancersv2'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'project'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'network'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = (
|
||||
'neutron_lbaas_dashboard.dashboards.project.ngloadbalancersv2.panel'
|
||||
'.NGLoadBalancers')
|
||||
|
||||
ADD_INSTALLED_APPS = ['neutron_lbaas_dashboard']
|
||||
|
||||
ADD_ANGULAR_MODULES = ['horizon.dashboard.project.lbaasv2']
|
||||
|
||||
# AUTO_DISCOVER_STATIC_FILES = True
|
||||
|
||||
ADD_JS_FILES = [
|
||||
'app/core/openstack-service-api/lbaasv2.service.js',
|
||||
'dashboard/project/lbaasv2/lbaasv2.module.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/table.controller.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.js',
|
||||
]
|
||||
|
||||
ADD_JS_SPEC_FILES = [
|
||||
'app/core/openstack-service-api/lbaasv2.service.spec.js',
|
||||
'dashboard/project/lbaasv2/lbaasv2.module.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/loadbalancers.module.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/table.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.spec.js',
|
||||
]
|
||||
#
|
||||
# ADD_SCSS_FILES = [
|
||||
#
|
||||
# ]
|
168
neutron_lbaas_dashboard/karma.conf.js
Normal file
168
neutron_lbaas_dashboard/karma.conf.js
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function (config) {
|
||||
var xstaticPath;
|
||||
var basePaths = [
|
||||
'../horizon/.venv'
|
||||
];
|
||||
|
||||
for (var i = 0; i < basePaths.length; i++) {
|
||||
var basePath = path.resolve(basePaths[i]);
|
||||
|
||||
if (fs.existsSync(basePath)) {
|
||||
xstaticPath = basePath + '/lib/python2.7/site-packages/xstatic/pkg/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!xstaticPath) {
|
||||
console.error('xStatic libraries not found, please set up venv');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
config.set({
|
||||
preprocessors: {
|
||||
// Used to collect templates for preprocessing.
|
||||
// NOTE: the templates must also be listed in the files section below.
|
||||
'./static/**/*.html': ['ng-html2js'],
|
||||
// Used to indicate files requiring coverage reports.
|
||||
'./static/**/!(*.spec).js': ['coverage'],
|
||||
},
|
||||
|
||||
// Sets up module to process templates.
|
||||
ngHtml2JsPreprocessor: {
|
||||
prependPrefix: '/static/',
|
||||
moduleName: 'templates'
|
||||
},
|
||||
|
||||
// Assumes you're in the top-level horizon directory.
|
||||
basePath: './',
|
||||
|
||||
// Contains both source and test files.
|
||||
files: [
|
||||
/*
|
||||
* shim, partly stolen from /i18n/js/horizon/
|
||||
* Contains expected items not provided elsewhere (dynamically by
|
||||
* Django or via jasmine template.
|
||||
*/
|
||||
'../../horizon/test-shim.js',
|
||||
|
||||
// from jasmine.html
|
||||
xstaticPath + 'jquery/data/jquery.js',
|
||||
xstaticPath + 'angular/data/angular.js',
|
||||
xstaticPath + 'angular/data/angular-mocks.js',
|
||||
xstaticPath + 'angular/data/angular-cookies.js',
|
||||
xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
|
||||
xstaticPath + 'angular_gettext/data/angular-gettext.js',
|
||||
xstaticPath + 'angular/data/angular-sanitize.js',
|
||||
xstaticPath + 'd3/data/d3.js',
|
||||
xstaticPath + 'rickshaw/data/rickshaw.js',
|
||||
xstaticPath + 'angular_smart_table/data/smart-table.js',
|
||||
xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js',
|
||||
xstaticPath + 'spin/data/spin.js',
|
||||
xstaticPath + 'spin/data/spin.jquery.js',
|
||||
|
||||
// TODO: These should be mocked.
|
||||
'../../horizon/horizon/static/horizon/js/horizon.js',
|
||||
|
||||
/**
|
||||
* Include framework source code from horizon that we need.
|
||||
* Otherwise, karma will not be able to find them when testing.
|
||||
* These files should be mocked in the foreseeable future.
|
||||
*/
|
||||
'../../horizon/horizon/static/framework/**/*.module.js',
|
||||
'../../horizon/horizon/static/framework/**/!(*.spec|*.mock).js',
|
||||
'../../horizon/openstack_dashboard/static/**/*.module.js',
|
||||
'../../horizon/openstack_dashboard/static/**/!(*.spec|*.mock).js',
|
||||
'../../horizon/openstack_dashboard/dashboards/**/static/**/*.module.js',
|
||||
'../../horizon/openstack_dashboard/dashboards/**/static/**/!(*.spec|*.mock).js',
|
||||
|
||||
/**
|
||||
* First, list all the files that defines application's angular modules.
|
||||
* Those files have extension of `.module.js`. The order among them is
|
||||
* not significant.
|
||||
*/
|
||||
'./static/**/*.module.js',
|
||||
|
||||
/**
|
||||
* Followed by other JavaScript files that defines angular providers
|
||||
* on the modules defined in files listed above. And they are not mock
|
||||
* files or spec files defined below. The order among them is not
|
||||
* significant.
|
||||
*/
|
||||
'./static/**/!(*.spec|*.mock).js',
|
||||
|
||||
/**
|
||||
* Then, list files for mocks with `mock.js` extension. The order
|
||||
* among them should not be significant.
|
||||
*/
|
||||
'../../horizon/openstack_dashboard/static/**/*.mock.js',
|
||||
//'./static/**/*.mock.js',
|
||||
|
||||
/**
|
||||
* Finally, list files for spec with `spec.js` extension. The order
|
||||
* among them should not be significant.
|
||||
*/
|
||||
'./static/**/*.spec.js',
|
||||
|
||||
/**
|
||||
* Angular external templates
|
||||
*/
|
||||
'./static/**/*.html'
|
||||
],
|
||||
|
||||
autoWatch: true,
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
browsers: ['PhantomJS'],
|
||||
|
||||
phantomjsLauncher: {
|
||||
// Have phantomjs exit if a ResourceError is encountered
|
||||
// (useful if karma exits without killing phantom)
|
||||
exitOnResourceError: true
|
||||
},
|
||||
|
||||
reporters: ['progress', 'coverage', 'threshold'],
|
||||
|
||||
plugins: [
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-jasmine',
|
||||
'karma-ng-html2js-preprocessor',
|
||||
'karma-coverage',
|
||||
'karma-threshold-reporter'
|
||||
],
|
||||
|
||||
coverageReporter: {
|
||||
type: 'html',
|
||||
dir: '../coverage-karma/'
|
||||
},
|
||||
|
||||
// Coverage threshold values.
|
||||
thresholdReporter: {
|
||||
statements: 100,
|
||||
branches: 100,
|
||||
functions: 100,
|
||||
lines: 100
|
||||
}
|
||||
});
|
||||
};
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.app.core.openstack-service-api')
|
||||
.factory('horizon.app.core.openstack-service-api.lbaasv2', lbaasv2API);
|
||||
|
||||
lbaasv2API.$inject = [
|
||||
'horizon.framework.util.http.service',
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name horizon.app.core.openstack-service-api.loadbalancers
|
||||
* @description Provides direct pass through to neutron LBaaS v2 with NO abstraction.
|
||||
*/
|
||||
function lbaasv2API(apiService, toastService) {
|
||||
var service = {
|
||||
getLoadBalancers: getLoadBalancers
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
///////////////
|
||||
|
||||
// Load Balancers
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.openstack-service-api.lbaasv2.getLoadBalancers
|
||||
* @description
|
||||
* Get a list of load balancers.
|
||||
*
|
||||
* The listing result is an object with property "items". Each item is
|
||||
* a load balancer.
|
||||
*/
|
||||
function getLoadBalancers() {
|
||||
return apiService.get('/api/lbaas/loadbalancers/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve load balancers.'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}());
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
describe('LBaaS v2 API', function() {
|
||||
var testCall, service;
|
||||
var apiService = {};
|
||||
var toastService = {};
|
||||
|
||||
beforeEach(module('horizon.mock.openstack-service-api', function($provide, initServices) {
|
||||
testCall = initServices($provide, apiService, toastService);
|
||||
}));
|
||||
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
|
||||
beforeEach(inject(['horizon.app.core.openstack-service-api.lbaasv2', function(lbaasv2API) {
|
||||
service = lbaasv2API;
|
||||
}]));
|
||||
|
||||
it('defines the service', function() {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
var tests = [
|
||||
{
|
||||
"func": "getLoadBalancers",
|
||||
"method": "get",
|
||||
"path": "/api/lbaas/loadbalancers/",
|
||||
"error": "Unable to retrieve load balancers."
|
||||
}
|
||||
];
|
||||
|
||||
// Iterate through the defined tests and apply as Jasmine specs.
|
||||
angular.forEach(tests, function(params) {
|
||||
it('defines the ' + params.func + ' call properly', function() {
|
||||
var callParams = [apiService, service, toastService, params];
|
||||
testCall.apply(this, callParams);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 overview
|
||||
* @name horizon.dashboard.project.lbaasv2
|
||||
* @description
|
||||
*
|
||||
* # horizon.dashboard.project.lbaasv2
|
||||
*
|
||||
* The LBaaS v2 dashboard's top level module.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2', [
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers'
|
||||
]);
|
||||
}());
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
describe('LBaaS v2 Module', function () {
|
||||
it('should be defined', function () {
|
||||
expect(angular.module('horizon.dashboard.project.lbaasv2')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.dashboard.project.lbaasv2.loadbalancers')
|
||||
.filter('operatingStatus', operatingStatusFilter)
|
||||
.filter('provisioningStatus', provisioningStatusFilter);
|
||||
|
||||
operatingStatusFilter.$inject = [
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
provisioningStatusFilter.$inject = [
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name operatingStatusFilter
|
||||
* @description
|
||||
* Takes raw load balancer operating status from the API and returns the user friendly status.
|
||||
*/
|
||||
function operatingStatusFilter(gettext) {
|
||||
var statuses = {
|
||||
'ONLINE': gettext('Online'),
|
||||
'OFFLINE': gettext('Offline'),
|
||||
'DEGRADED': gettext('Degraded'),
|
||||
'ERROR': gettext('Error')
|
||||
};
|
||||
|
||||
return function (input) {
|
||||
var result = statuses[input];
|
||||
return angular.isDefined(result) ? result : input;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name provisioningStatusFilter
|
||||
* @description
|
||||
* Takes raw load balancer provisioning status from the API and returns the user friendly status.
|
||||
*/
|
||||
function provisioningStatusFilter(gettext) {
|
||||
var statuses = {
|
||||
'ACTIVE': gettext('Active'),
|
||||
'PENDING_CREATE': gettext('Pending Create'),
|
||||
'PENDING_UPDATE': gettext('Pending Update'),
|
||||
'PENDING_DELETE': gettext('Pending Delete'),
|
||||
'ERROR': gettext('Error')
|
||||
};
|
||||
|
||||
return function (input) {
|
||||
var result = statuses[input];
|
||||
return angular.isDefined(result) ? result : input;
|
||||
};
|
||||
}
|
||||
|
||||
}());
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Filters', function () {
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2.loadbalancers'));
|
||||
|
||||
describe('operatingStatus', function () {
|
||||
var operatingStatusFilter;
|
||||
beforeEach(inject(function (_operatingStatusFilter_) {
|
||||
operatingStatusFilter = _operatingStatusFilter_;
|
||||
}));
|
||||
|
||||
it('Returns value when key is present', function () {
|
||||
expect(operatingStatusFilter('ONLINE')).toBe('Online');
|
||||
});
|
||||
|
||||
it('Returns input when key is not present', function () {
|
||||
expect(operatingStatusFilter('unknown')).toBe('unknown');
|
||||
});
|
||||
});
|
||||
|
||||
describe('provisioningStatus', function () {
|
||||
var provisioningStatusFilter;
|
||||
beforeEach(inject(function (_provisioningStatusFilter_) {
|
||||
provisioningStatusFilter = _provisioningStatusFilter_;
|
||||
}));
|
||||
|
||||
it('Returns value when key is present', function () {
|
||||
expect(provisioningStatusFilter('ACTIVE')).toBe('Active');
|
||||
});
|
||||
|
||||
it('Returns input when key is not present', function () {
|
||||
expect(provisioningStatusFilter('unknown')).toBe('unknown');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 overview
|
||||
* @ngname horizon.dashboard.project.lbaasv2.loadbalancers
|
||||
*
|
||||
* @description
|
||||
* Provides the services and widgets required to support and display the project load
|
||||
* balancers v2 panel.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers', [])
|
||||
.config(config);
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider'
|
||||
];
|
||||
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'dashboard/project/lbaasv2/loadbalancers/';
|
||||
$provide.constant('horizon.dashboard.project.lbaasv2.loadbalancers.basePath', path);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Module', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.project.lbaasv2.loadbalancers')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('LBaaS v2 Load Balancers Module Base Path', function () {
|
||||
var basePath, staticUrl;
|
||||
|
||||
beforeEach(module('horizon.dashboard.project'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2.loadbalancers'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
basePath = $injector.get('horizon.dashboard.project.lbaasv2.loadbalancers.basePath');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(basePath).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be correct', function () {
|
||||
expect(basePath).toEqual(staticUrl + 'dashboard/project/lbaasv2/loadbalancers/');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('loadBalancersTableController', LoadBalancersTableController);
|
||||
|
||||
LoadBalancersTableController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.basePath',
|
||||
'horizon.app.core.openstack-service-api.lbaasv2'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name LoadBalancersTableController
|
||||
*
|
||||
* @description
|
||||
* Controller for the LBaaS v2 load balancers table.
|
||||
* Serves as the focal point for table actions.
|
||||
*/
|
||||
function LoadBalancersTableController(basepath, api) {
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.items = [];
|
||||
ctrl.src = [];
|
||||
ctrl.checked = {};
|
||||
ctrl.path = basepath;
|
||||
|
||||
init();
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function init() {
|
||||
api.getLoadBalancers().success(success);
|
||||
}
|
||||
|
||||
function success(response) {
|
||||
ctrl.src = response.items;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Table Controller', function() {
|
||||
var controller, lbaasv2API, staticUrl, items = [];
|
||||
|
||||
function fakeAPI() {
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback({ items: items });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.framework.util.http'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2.loadbalancers'));
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2');
|
||||
controller = $injector.get('$controller');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
spyOn(lbaasv2API, 'getLoadBalancers').and.callFake(fakeAPI);
|
||||
}));
|
||||
|
||||
function createController() {
|
||||
return controller('loadBalancersTableController', {
|
||||
lbaasv2API: lbaasv2API
|
||||
});
|
||||
}
|
||||
|
||||
it('should initialize correctly', function() {
|
||||
var ctrl = createController();
|
||||
expect(ctrl.items).toEqual([]);
|
||||
expect(ctrl.src).toEqual(items);
|
||||
expect(ctrl.checked).toEqual({});
|
||||
});
|
||||
|
||||
it('should set path properly', function() {
|
||||
var path = staticUrl + 'dashboard/project/lbaasv2/loadbalancers/';
|
||||
expect(createController().path).toEqual(path);
|
||||
});
|
||||
|
||||
it('should invoke lbaasv2 apis', function() {
|
||||
createController();
|
||||
expect(lbaasv2API.getLoadBalancers).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,138 @@
|
||||
<table ng-controller="loadBalancersTableController as table"
|
||||
hz-table ng-cloak
|
||||
st-table="table.items"
|
||||
st-safe-src="table.src"
|
||||
default-sort="name"
|
||||
default-sort-reverse="false"
|
||||
class="table-striped table-rsp table-detail modern">
|
||||
<!--
|
||||
TODO(jpomero): This table pattern does not allow for extensibility and should be revisited
|
||||
once horizon implements a better one.
|
||||
-->
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<!--
|
||||
Table-batch-actions:
|
||||
This is where batch actions like searching, creating, and deleting.
|
||||
-->
|
||||
<th colspan="100" class="search-header">
|
||||
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
|
||||
</hz-search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<!--
|
||||
Table-column-headers:
|
||||
This is where we declaratively define the table column headers.
|
||||
Include select-col if you want to select all.
|
||||
Include expander if you want to inline details.
|
||||
Include action-col if you want to perform actions.
|
||||
-->
|
||||
<th class="select-col">
|
||||
<input type="checkbox" hz-select-all="table.items">
|
||||
</th>
|
||||
|
||||
<th class="expander"></th>
|
||||
|
||||
<th class="rsp-p1" st-sort="name" st-sort-default="name" translate>Name</th>
|
||||
<th class="rsp-p1" st-sort="description" translate>Description</th>
|
||||
<th class="rsp-p1" st-sort="operating_status" translate>Operating Status</th>
|
||||
<th class="rsp-p1" st-sort="provisioning_status" translate>Provisioning Status</th>
|
||||
<th class="rsp-p2" st-sort="vip_address" translate>IP Address</th>
|
||||
<th class="rsp-p2" st-sort="listeners.length" translate>Listeners</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<!--
|
||||
Table-rows:
|
||||
This is where we declaratively define the table columns.
|
||||
Include select-col if you want to select all.
|
||||
Include expander if you want to inline details.
|
||||
Include action-col if you want to perform actions.
|
||||
rsp-p1 rsp-p2 are responsive priority as user resizes window.
|
||||
-->
|
||||
<tr ng-repeat-start="item in table.items track by item.id"
|
||||
ng-class="{'st-selected': checked[item.id]}">
|
||||
|
||||
<td class="select-col">
|
||||
<input type="checkbox"
|
||||
ng-model="selected[item.id].checked"
|
||||
hz-select="item">
|
||||
</td>
|
||||
<td class="expander">
|
||||
<i class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
duration="200">
|
||||
</i>
|
||||
</td>
|
||||
<td class="rsp-p1">{$ item.name $}</td>
|
||||
<td class="rsp-p1">{$ item.description | noValue $}</td>
|
||||
<td class="rsp-p1">{$ item.operating_status | operatingStatus $}</td>
|
||||
<td class="rsp-p1">{$ item.provisioning_status | provisioningStatus $}</td>
|
||||
<td class="rsp-p2">{$ item.vip_address $}</td>
|
||||
<td class="rsp-p2">{$ item.listeners.length $}</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat-end class="detail-row">
|
||||
<!--
|
||||
Detail-row:
|
||||
Contains detailed information on this item.
|
||||
Can be toggled using the chevron button.
|
||||
Ensure colspan is greater or equal to number of column-headers.
|
||||
-->
|
||||
<td class="detail" colspan="100">
|
||||
<!--
|
||||
The responsive columns that disappear typically should reappear here
|
||||
with the same responsive priority that they disappear.
|
||||
E.g. table header with rsp-p2 should be here with rsp-alt-p2
|
||||
-->
|
||||
<div class="row">
|
||||
<span class="rsp-alt-p2">
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>IP Address</dt>
|
||||
<dd>{$ item.vip_address $}</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Listeners</dt>
|
||||
<dd>{$ item.listeners.length $}</dd>
|
||||
</dl>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Provider</dt>
|
||||
<dd>{$ item.provider $}</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Admin State Up</dt>
|
||||
<dd>{$ item.admin_state_up | yesno $}</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ item.id $}</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Subnet ID</dt>
|
||||
<dd>{$ item.vip_subnet_id $}</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Port ID</dt>
|
||||
<dd>{$ item.vip_port_id $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<!--
|
||||
Table-footer:
|
||||
This is where we display number of items and pagination controls.
|
||||
-->
|
||||
<tfoot hz-table-footer items="table.items"></tfoot>
|
||||
|
||||
</table>
|
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"name": "neutron-lbaas-dashboard",
|
||||
"description": "Neutron LBaaS v2 Dashboard",
|
||||
"repository": "none",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
"eslint": "1.2.0",
|
||||
"eslint-config-openstack": "1.2.2",
|
||||
"eslint-plugin-angular": "0.4.0",
|
||||
"jasmine-core": "2.2.0",
|
||||
"karma": "0.12.31",
|
||||
"karma-chrome-launcher": "0.1.8",
|
||||
"karma-cli": "0.0.4",
|
||||
"karma-coverage": "0.3.1",
|
||||
"karma-jasmine": "0.3.5",
|
||||
"karma-ng-html2js-preprocessor": "0.1.2",
|
||||
"karma-phantomjs-launcher": "0.2.0",
|
||||
"karma-threshold-reporter": "0.1.15",
|
||||
"phantomjs": "1.9.17"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "karma start neutron_lbaas_dashboard/karma.conf.js --single-run",
|
||||
"lint": "eslint --no-color neutron_lbaas_dashboard/static"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user