Merge "Trunks panel: details for trunks and subports"
This commit is contained in:
commit
2f0756fdd1
@ -786,6 +786,13 @@ def trunk_delete(request, trunk_id):
|
|||||||
neutronclient(request).delete_trunk(trunk_id)
|
neutronclient(request).delete_trunk(trunk_id)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def trunk_show(request, trunk_id):
|
||||||
|
LOG.debug("trunk_show(): trunk_id=%s", trunk_id)
|
||||||
|
trunk = neutronclient(request).show_trunk(trunk_id).get('trunk')
|
||||||
|
return Trunk(trunk)
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
@profiler.trace
|
||||||
def network_list(request, **params):
|
def network_list(request, **params):
|
||||||
LOG.debug("network_list(): params=%s", params)
|
LOG.debug("network_list(): params=%s", params)
|
||||||
|
@ -146,6 +146,12 @@ class Trunk(generic.View):
|
|||||||
def delete(self, request, trunk_id):
|
def delete(self, request, trunk_id):
|
||||||
api.neutron.trunk_delete(request, trunk_id)
|
api.neutron.trunk_delete(request, trunk_id)
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request, trunk_id):
|
||||||
|
"""Get a specific trunk"""
|
||||||
|
trunk = api.neutron.trunk_show(request, trunk_id)
|
||||||
|
return trunk.to_dict()
|
||||||
|
|
||||||
|
|
||||||
@urls.register
|
@urls.register
|
||||||
class Trunks(generic.View):
|
class Trunks(generic.View):
|
||||||
|
@ -21,4 +21,6 @@ from horizon.browsers.views import AngularIndexView
|
|||||||
title = _("Trunks")
|
title = _("Trunks")
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', AngularIndexView.as_view(title=title), name='index'),
|
url(r'^$', AngularIndexView.as_view(title=title), name='index'),
|
||||||
|
url(r'^(?P<trunk_id>[^/]+)/$', AngularIndexView.as_view(title=title),
|
||||||
|
name='detail'),
|
||||||
]
|
]
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
getQosPolicy: getQosPolicy,
|
getQosPolicy: getQosPolicy,
|
||||||
getQoSPolicies: getQoSPolicies,
|
getQoSPolicies: getQoSPolicies,
|
||||||
getSubnets: getSubnets,
|
getSubnets: getSubnets,
|
||||||
|
getTrunk: getTrunk,
|
||||||
getTrunks: getTrunks,
|
getTrunks: getTrunks,
|
||||||
updateProjectQuota: updateProjectQuota
|
updateProjectQuota: updateProjectQuota
|
||||||
};
|
};
|
||||||
@ -54,6 +55,15 @@
|
|||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
|
// NOTE(bence romsics): Technically we replace ISO 8061 time stamps with
|
||||||
|
// date objects. We do this because the date objects will stringify to human
|
||||||
|
// readable datetimes in local time (ie. in the browser's time zone) when
|
||||||
|
// displayed.
|
||||||
|
function convertDatesHumanReadable(apidict) {
|
||||||
|
apidict.created_at = new Date(apidict.created_at);
|
||||||
|
apidict.updated_at = new Date(apidict.updated_at);
|
||||||
|
}
|
||||||
|
|
||||||
// Neutron Services
|
// Neutron Services
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,6 +379,27 @@
|
|||||||
|
|
||||||
// Trunks
|
// Trunks
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name getTrunk
|
||||||
|
* @description
|
||||||
|
* Get a single trunk by ID
|
||||||
|
*
|
||||||
|
* @param {string} id
|
||||||
|
* Specifies the id of the trunk to request.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
function getTrunk(id) {
|
||||||
|
return apiService.get('/api/neutron/trunks/' + id + '/')
|
||||||
|
.success(function(trunk) {
|
||||||
|
convertDatesHumanReadable(trunk);
|
||||||
|
})
|
||||||
|
.error(function () {
|
||||||
|
var msg = gettext('Unable to retrieve the trunk with id: %(id)s');
|
||||||
|
toastService.add('error', interpolate(msg, { id : id }, true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name getTrunks
|
* @name getTrunks
|
||||||
* @description
|
* @description
|
||||||
@ -379,6 +410,11 @@
|
|||||||
function getTrunks(params) {
|
function getTrunks(params) {
|
||||||
var config = params ? {'params' : params} : {};
|
var config = params ? {'params' : params} : {};
|
||||||
return apiService.get('/api/neutron/trunks/', config)
|
return apiService.get('/api/neutron/trunks/', config)
|
||||||
|
.success(function(trunks) {
|
||||||
|
trunks.items.forEach(function(trunk) {
|
||||||
|
convertDatesHumanReadable(trunk);
|
||||||
|
});
|
||||||
|
})
|
||||||
.error(function () {
|
.error(function () {
|
||||||
toastService.add('error', gettext('Unable to retrieve the trunks.'));
|
toastService.add('error', gettext('Unable to retrieve the trunks.'));
|
||||||
});
|
});
|
||||||
|
@ -132,6 +132,15 @@
|
|||||||
42
|
42
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"func": "getTrunk",
|
||||||
|
"method": "get",
|
||||||
|
"path": "/api/neutron/trunks/42/",
|
||||||
|
"error": "Unable to retrieve the trunk with id: 42",
|
||||||
|
"testInput": [
|
||||||
|
42
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"func": "getTrunks",
|
"func": "getTrunks",
|
||||||
"method": "get",
|
"method": "get",
|
||||||
|
56
openstack_dashboard/static/app/core/trunks/details/details.module.js
Executable file
56
openstack_dashboard/static/app/core/trunks/details/details.module.js
Executable file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Ericsson
|
||||||
|
*
|
||||||
|
* 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.app.core.trunks.details
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides details features for trunks.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('horizon.app.core.trunks.details', [
|
||||||
|
'horizon.framework.conf',
|
||||||
|
'horizon.app.core'
|
||||||
|
])
|
||||||
|
.run(registerTrunkDetails);
|
||||||
|
|
||||||
|
registerTrunkDetails.$inject = [
|
||||||
|
'horizon.app.core.trunks.basePath',
|
||||||
|
'horizon.app.core.trunks.resourceType',
|
||||||
|
'horizon.app.core.trunks.service',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
function registerTrunkDetails(
|
||||||
|
basePath,
|
||||||
|
trunkResourceType,
|
||||||
|
trunkService,
|
||||||
|
registry
|
||||||
|
) {
|
||||||
|
registry.getResourceType(trunkResourceType)
|
||||||
|
.setLoadFunction(trunkService.getTrunkPromise)
|
||||||
|
.detailsViews.append({
|
||||||
|
id: 'trunkDetailsOverview',
|
||||||
|
name: gettext('Overview'),
|
||||||
|
template: basePath + 'details/overview.html'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
72
openstack_dashboard/static/app/core/trunks/details/overview.controller.js
Executable file
72
openstack_dashboard/static/app/core/trunks/details/overview.controller.js
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Ericsson
|
||||||
|
*
|
||||||
|
* 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.trunks')
|
||||||
|
.controller('TrunkOverviewController', TrunkOverviewController);
|
||||||
|
|
||||||
|
TrunkOverviewController.$inject = [
|
||||||
|
'horizon.app.core.trunks.resourceType',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'horizon.app.core.openstack-service-api.userSession',
|
||||||
|
'$scope'
|
||||||
|
];
|
||||||
|
|
||||||
|
function TrunkOverviewController(
|
||||||
|
trunkResourceTypeCode,
|
||||||
|
registry,
|
||||||
|
userSession,
|
||||||
|
$scope
|
||||||
|
) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
ctrl.resourceType = registry.getResourceType(trunkResourceTypeCode);
|
||||||
|
ctrl.tableConfig = {
|
||||||
|
selectAll: false,
|
||||||
|
expand: false,
|
||||||
|
trackId: 'segmentation_id',
|
||||||
|
/*
|
||||||
|
* getTableColumns here won't work as that will give back the
|
||||||
|
* columns for trunk, but here we need columns only for the
|
||||||
|
* subports, which is a (list of) dictionary(ies) in the
|
||||||
|
* trunk dictionary.
|
||||||
|
*/
|
||||||
|
columns: [
|
||||||
|
{id: 'segmentation_type', title: gettext('Segmentation Type'),
|
||||||
|
priority: 1, sortDefault: true},
|
||||||
|
{id: 'segmentation_id', title: gettext('Segmentation ID'),
|
||||||
|
priority: 1, sortDefault: true},
|
||||||
|
{id: 'port_id', title: gettext('Port ID'), priority: 1}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.context.loadPromise.then(onGetTrunk);
|
||||||
|
|
||||||
|
function onGetTrunk(trunk) {
|
||||||
|
ctrl.trunk = trunk.data;
|
||||||
|
|
||||||
|
userSession.get().then(setProject);
|
||||||
|
|
||||||
|
function setProject(session) {
|
||||||
|
ctrl.projectId = session.project_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Ericsson
|
||||||
|
*
|
||||||
|
* 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('trunk overview controller', function() {
|
||||||
|
var ctrl;
|
||||||
|
var sessionObj = {project_id: '12'};
|
||||||
|
var neutron = {
|
||||||
|
getNamespaces: angular.noop
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(module('horizon.app.core.trunks'));
|
||||||
|
beforeEach(module('horizon.framework.conf'));
|
||||||
|
beforeEach(inject(function($controller, $q, $injector) {
|
||||||
|
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
||||||
|
var deferred = $q.defer();
|
||||||
|
var sessionDeferred = $q.defer();
|
||||||
|
deferred.resolve({data: {sub_ports: [{'port_id': '1', 'seg_id': 2}, [], {}]}});
|
||||||
|
sessionDeferred.resolve(sessionObj);
|
||||||
|
spyOn(neutron, 'getNamespaces').and.returnValue(deferred.promise);
|
||||||
|
spyOn(session, 'get').and.returnValue(sessionDeferred.promise);
|
||||||
|
ctrl = $controller('TrunkOverviewController',
|
||||||
|
{
|
||||||
|
'$scope': {context: {loadPromise: deferred.promise}}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('sets ctrl.resourceType', function() {
|
||||||
|
expect(ctrl.resourceType).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets ctrl.trunk.sub_ports', inject(function($timeout) {
|
||||||
|
$timeout.flush();
|
||||||
|
expect(ctrl.trunk).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports[0]).toEqual({'port_id': '1', 'seg_id': 2});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('sets ctrl.trunk.sub_ports if empty array', inject(function($timeout) {
|
||||||
|
$timeout.flush();
|
||||||
|
expect(ctrl.trunk).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports[1]).toEqual([]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('sets ctrl.trunk.sub_ports if empty object', inject(function($timeout) {
|
||||||
|
$timeout.flush();
|
||||||
|
expect(ctrl.trunk).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports).toBeDefined();
|
||||||
|
expect(ctrl.trunk.sub_ports[2]).toEqual({});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('sets ctrl.projectId', inject(function($timeout) {
|
||||||
|
$timeout.flush();
|
||||||
|
expect(ctrl.projectId).toBe(sessionObj.project_id);
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
19
openstack_dashboard/static/app/core/trunks/details/overview.html
Executable file
19
openstack_dashboard/static/app/core/trunks/details/overview.html
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
<div ng-controller="TrunkOverviewController as ctrl">
|
||||||
|
<hz-resource-property-list
|
||||||
|
resource-type-name="OS::Neutron::Trunk"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
item="ctrl.trunk"
|
||||||
|
property-groups="[[
|
||||||
|
'id', 'name', 'description', 'port_id', 'status', 'admin_state',
|
||||||
|
'created_at', 'updated_at']]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
<h2 class="h4">{$ ::'Subports' | translate $}</h2>
|
||||||
|
<hr>
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<hz-dynamic-table
|
||||||
|
config="ctrl.tableConfig"
|
||||||
|
items="ctrl.trunk.sub_ports"
|
||||||
|
table="ctrl">
|
||||||
|
</hz-dynamic-table>
|
||||||
|
</dl>
|
||||||
|
</div>
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/*
|
||||||
* Copyright 2017 Ericsson
|
* Copyright 2017 Ericsson
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -30,6 +30,7 @@
|
|||||||
'ngRoute',
|
'ngRoute',
|
||||||
'horizon.framework.conf',
|
'horizon.framework.conf',
|
||||||
'horizon.app.core.trunks.actions',
|
'horizon.app.core.trunks.actions',
|
||||||
|
'horizon.app.core.trunks.details',
|
||||||
'horizon.app.core'
|
'horizon.app.core'
|
||||||
])
|
])
|
||||||
.constant('horizon.app.core.trunks.resourceType', 'OS::Neutron::Trunk')
|
.constant('horizon.app.core.trunks.resourceType', 'OS::Neutron::Trunk')
|
||||||
@ -58,7 +59,8 @@
|
|||||||
.append({
|
.append({
|
||||||
id: 'name_or_id',
|
id: 'name_or_id',
|
||||||
priority: 1,
|
priority: 1,
|
||||||
sortDefault: true
|
sortDefault: true,
|
||||||
|
urlFunction: trunksService.getDetailsPath
|
||||||
})
|
})
|
||||||
.append({
|
.append({
|
||||||
id: 'port_id',
|
id: 'port_id',
|
||||||
@ -156,6 +158,14 @@
|
|||||||
$routeProvider.when('/project/trunks', {
|
$routeProvider.when('/project/trunks', {
|
||||||
templateUrl: path + 'panel.html'
|
templateUrl: path + 'panel.html'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$routeProvider.when('/project/trunks/:id', {
|
||||||
|
redirectTo: goToAngularDetails
|
||||||
|
});
|
||||||
|
|
||||||
|
function goToAngularDetails(params) {
|
||||||
|
return detailRoute + 'OS::Neutron::Trunk/' + params.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/*
|
||||||
* Copyright 2017 Ericsson
|
* Copyright 2017 Ericsson
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -22,7 +22,9 @@
|
|||||||
|
|
||||||
trunksService.$inject = [
|
trunksService.$inject = [
|
||||||
'horizon.app.core.openstack-service-api.neutron',
|
'horizon.app.core.openstack-service-api.neutron',
|
||||||
'horizon.app.core.openstack-service-api.userSession'
|
'horizon.app.core.openstack-service-api.userSession',
|
||||||
|
'horizon.app.core.detailRoute',
|
||||||
|
'$location'
|
||||||
];
|
];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -35,12 +37,26 @@
|
|||||||
* but do not need to be restricted to such use. Each exposed function
|
* but do not need to be restricted to such use. Each exposed function
|
||||||
* is documented below.
|
* is documented below.
|
||||||
*/
|
*/
|
||||||
function trunksService(neutron, userSession) {
|
function trunksService(neutron, userSession, detailRoute, $location) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getTrunksPromise: getTrunksPromise
|
getDetailsPath: getDetailsPath,
|
||||||
|
getTrunksPromise: getTrunksPromise,
|
||||||
|
getTrunkPromise: getTrunkPromise
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ngdoc function
|
||||||
|
* @name getDetailsPath
|
||||||
|
* @param item {Object} - The trunk object
|
||||||
|
* @description
|
||||||
|
* Given a Trunk object, returns the relative path to the details
|
||||||
|
* view.
|
||||||
|
*/
|
||||||
|
function getDetailsPath(item) {
|
||||||
|
return detailRoute + 'OS::Neutron::Trunk/' + item.id;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name getTrunksPromise
|
* @name getTrunksPromise
|
||||||
@ -56,6 +72,25 @@
|
|||||||
return neutron.getTrunks(params);
|
return neutron.getTrunks(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ngdoc function
|
||||||
|
* @name getTrunkPromise
|
||||||
|
* @description
|
||||||
|
* Given an id, returns a promise for the trunk data.
|
||||||
|
*/
|
||||||
|
function getTrunkPromise(identifier) {
|
||||||
|
return neutron.getTrunk(identifier).then(getTrunkSuccess, getTrunkError);
|
||||||
|
|
||||||
|
function getTrunkSuccess(trunk) {
|
||||||
|
return trunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTrunkError(trunk) {
|
||||||
|
$location.url('project/trunks');
|
||||||
|
return trunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/*
|
||||||
* Copyright 2017 Ericsson
|
* Copyright 2017 Ericsson
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
@ -26,6 +26,19 @@
|
|||||||
service = $injector.get('horizon.app.core.trunks.service');
|
service = $injector.get('horizon.app.core.trunks.service');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe('getTrunkPromise', function() {
|
||||||
|
it("provides a promise", inject(function($q, $injector, $timeout) {
|
||||||
|
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
||||||
|
var deferred = $q.defer();
|
||||||
|
spyOn(neutron, 'getTrunk').and.returnValue(deferred.promise);
|
||||||
|
var result = service.getTrunkPromise({});
|
||||||
|
deferred.resolve({data: {id: 1, updated_at: 'May29'}});
|
||||||
|
$timeout.flush();
|
||||||
|
expect(neutron.getTrunk).toHaveBeenCalled();
|
||||||
|
expect(result.$$state.value.data.updated_at).toBe('May29');
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
describe('getTrunksPromise', function() {
|
describe('getTrunksPromise', function() {
|
||||||
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
|
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
|
||||||
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
||||||
|
@ -167,6 +167,16 @@ class NeutronTrunkTestCase(test.TestCase):
|
|||||||
neutron.Trunk().delete(request, 1)
|
neutron.Trunk().delete(request, 1)
|
||||||
client.trunk_delete.assert_called_once_with(request, 1)
|
client.trunk_delete.assert_called_once_with(request, 1)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron.api, 'neutron')
|
||||||
|
def test_trunk_get(self, client):
|
||||||
|
trunk_id = TEST.api_trunks.first().get("id")
|
||||||
|
request = self.mock_rest_request(GET={"trunk_id": trunk_id})
|
||||||
|
client.trunk_show.return_value = self.trunks.first()
|
||||||
|
response = neutron.Trunk().get(request, trunk_id=trunk_id)
|
||||||
|
self.assertStatusCode(response, 200)
|
||||||
|
client.trunk_show.assert_called_once_with(
|
||||||
|
request, trunk_id)
|
||||||
|
|
||||||
|
|
||||||
class NeutronTrunksTestCase(test.TestCase):
|
class NeutronTrunksTestCase(test.TestCase):
|
||||||
|
|
||||||
|
@ -430,6 +430,17 @@ class NeutronApiTests(test.APITestCase):
|
|||||||
for t in ret_val:
|
for t in ret_val:
|
||||||
self.assertIsInstance(t, api.neutron.Trunk)
|
self.assertIsInstance(t, api.neutron.Trunk)
|
||||||
|
|
||||||
|
def test_trunk_show(self):
|
||||||
|
trunk = {'trunk': self.api_trunks.first()}
|
||||||
|
trunk_id = self.api_trunks.first()['id']
|
||||||
|
|
||||||
|
neutron_client = self.stub_neutronclient()
|
||||||
|
neutron_client.show_trunk(trunk_id).AndReturn(trunk)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
ret_val = api.neutron.trunk_show(self.request, trunk_id)
|
||||||
|
self.assertIsInstance(ret_val, api.neutron.Trunk)
|
||||||
|
|
||||||
def test_trunk_object(self):
|
def test_trunk_object(self):
|
||||||
trunk = self.api_trunks.first().copy()
|
trunk = self.api_trunks.first().copy()
|
||||||
obj = api.neutron.Trunk(trunk)
|
obj = api.neutron.Trunk(trunk)
|
||||||
|
11
releasenotes/notes/bp-neutron-trunk-ui-72e05888e68502c4.yaml
Normal file
11
releasenotes/notes/bp-neutron-trunk-ui-72e05888e68502c4.yaml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
[`blueprint neutron-trunk-ui <https://blueprints.launchpad.net/horizon/+spec/neutron-trunk-ui>`_]
|
||||||
|
Add partial support for Neutron Trunks. Since the panel is
|
||||||
|
incomplete in Pike, it is disabled by default. An example 'enabled'
|
||||||
|
file is supplied. After enabling it the Project/Network/Trunks
|
||||||
|
panel turns on if Neutron API extension 'trunk' is available. It
|
||||||
|
displays information about trunks. The details page for each trunk
|
||||||
|
also shows information about subports of that trunk.
|
||||||
|
Currently supported actions: delete.
|
Loading…
Reference in New Issue
Block a user