New readonly panel for trunks
Enable display of trunks on the project dashboard. To test it devstack needs to have neutron with trunk support, eg: local.conf: enable_plugin neutron https://git.openstack.org/openstack/neutron enable_service q-trunk No special horizon config is needed. As long as the 'trunk' API extension is available (openstack extension show trunk) the panel should automatically appear under Project/Network/Trunks. Co-Authored-By: Akihiro Motoki <amotoki@gmail.com> Co-Authored-By: Bence Romsics <bence.romsics@ericsson.com> Change-Id: Iacb83f22f81e09457953622e61065f0bb2c27407 Partially-Implements: blueprint neutron-trunk-ui
This commit is contained in:
parent
071ba2cb08
commit
3524b3d4f7
@ -107,6 +107,20 @@ class Subnet(NeutronAPIDictWrapper):
|
||||
super(Subnet, self).__init__(apidict)
|
||||
|
||||
|
||||
class Trunk(NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron trunks."""
|
||||
|
||||
@property
|
||||
def subport_count(self):
|
||||
return len(self._apidict.get('sub_ports', []))
|
||||
|
||||
def to_dict(self):
|
||||
trunk_dict = super(Trunk, self).to_dict()
|
||||
trunk_dict['name_or_id'] = self.name_or_id
|
||||
trunk_dict['subport_count'] = self.subport_count
|
||||
return trunk_dict
|
||||
|
||||
|
||||
class SubnetPool(NeutronAPIDictWrapper):
|
||||
"""Wrapper for neutron subnetpools."""
|
||||
|
||||
@ -623,6 +637,13 @@ def list_resources_with_long_filters(list_method,
|
||||
return resources
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def trunk_list(request, **params):
|
||||
LOG.debug("trunk_list(): params=%s", params)
|
||||
trunks = neutronclient(request).list_trunks(**params).get('trunks')
|
||||
return [Trunk(t) for t in trunks]
|
||||
|
||||
|
||||
@profiler.trace
|
||||
def network_list(request, **params):
|
||||
LOG.debug("network_list(): params=%s", params)
|
||||
|
@ -136,6 +136,23 @@ class Ports(generic.View):
|
||||
return{'items': [n.to_dict() for n in result]}
|
||||
|
||||
|
||||
@urls.register
|
||||
class Trunks(generic.View):
|
||||
"""API for neutron Trunks
|
||||
"""
|
||||
url_regex = r'neutron/trunks/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get a list of trunks
|
||||
|
||||
The listing result is an object with property "items".
|
||||
Each item is a trunk.
|
||||
"""
|
||||
result = api.neutron.trunk_list(request, **request.GET)
|
||||
return {'items': [n.to_dict() for n in result]}
|
||||
|
||||
|
||||
@urls.register
|
||||
class Services(generic.View):
|
||||
"""API for Neutron agents
|
||||
|
44
openstack_dashboard/dashboards/project/trunks/panel.py
Normal file
44
openstack_dashboard/dashboards/project/trunks/panel.py
Normal file
@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
import horizon
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Trunks(horizon.Panel):
|
||||
name = _("Trunks")
|
||||
slug = "trunks"
|
||||
permissions = ('openstack.services.network',)
|
||||
|
||||
def allowed(self, context):
|
||||
request = context['request']
|
||||
try:
|
||||
return (
|
||||
super(Trunks, self).allowed(context)
|
||||
and request.user.has_perms(self.permissions)
|
||||
and neutron.is_extension_supported(request,
|
||||
extension_alias='trunk')
|
||||
)
|
||||
except Exception:
|
||||
LOG.error("Call to list enabled services failed. This is likely "
|
||||
"due to a problem communicating with the Neutron "
|
||||
"endpoint. Trunks panel will not be displayed.")
|
||||
return False
|
24
openstack_dashboard/dashboards/project/trunks/urls.py
Normal file
24
openstack_dashboard/dashboards/project/trunks/urls.py
Normal file
@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon.browsers.views import AngularIndexView
|
||||
|
||||
|
||||
title = _("Trunks")
|
||||
urlpatterns = [
|
||||
url(r'^$', AngularIndexView.as_view(title=title), name='index'),
|
||||
]
|
10
openstack_dashboard/enabled/_1500_project_trunks_panel.py
Normal file
10
openstack_dashboard/enabled/_1500_project_trunks_panel.py
Normal file
@ -0,0 +1,10 @@
|
||||
# The slug of the panel to be added to HORIZON_CONFIG. Required.
|
||||
PANEL = 'trunks'
|
||||
# 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 = \
|
||||
'openstack_dashboard.dashboards.project.trunks.panel.Trunks'
|
@ -38,6 +38,7 @@
|
||||
'horizon.app.core.images',
|
||||
'horizon.app.core.metadata',
|
||||
'horizon.app.core.openstack-service-api',
|
||||
'horizon.app.core.trunks',
|
||||
'horizon.app.core.workflow',
|
||||
'horizon.framework.conf',
|
||||
'horizon.framework.util',
|
||||
|
@ -43,7 +43,8 @@
|
||||
getAgents: getAgents,
|
||||
getExtensions: getExtensions,
|
||||
getDefaultQuotaSets: getDefaultQuotaSets,
|
||||
updateProjectQuota: updateProjectQuota
|
||||
updateProjectQuota: updateProjectQuota,
|
||||
getTrunks: getTrunks
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -332,6 +333,22 @@
|
||||
toastService.add('error', gettext('Unable to update project quota data.'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Trunks
|
||||
|
||||
/**
|
||||
* @name getTrunks
|
||||
* @description
|
||||
* Get a list of trunks for a tenant.
|
||||
*
|
||||
* @returns {Object} An object with property "items". Each item is a trunk.
|
||||
*/
|
||||
function getTrunks(params) {
|
||||
var config = params ? {'params' : params} : {};
|
||||
return apiService.get('/api/neutron/trunks/', config)
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the trunks.'));
|
||||
});
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
@ -125,6 +125,13 @@
|
||||
},
|
||||
42
|
||||
]
|
||||
},
|
||||
{
|
||||
"func": "getTrunks",
|
||||
"method": "get",
|
||||
"path": "/api/neutron/trunks/",
|
||||
"data": {},
|
||||
"error": "Unable to retrieve the trunks."
|
||||
}
|
||||
];
|
||||
|
||||
|
3
openstack_dashboard/static/app/core/trunks/panel.html
Normal file
3
openstack_dashboard/static/app/core/trunks/panel.html
Normal file
@ -0,0 +1,3 @@
|
||||
<hz-resource-panel resource-type-name="OS::Neutron::Trunk">
|
||||
<hz-resource-table resource-type-name="OS::Neutron::Trunk"></hz-resource-table>
|
||||
</hz-resource-panel>
|
17
openstack_dashboard/static/app/core/trunks/summary.html
Normal file
17
openstack_dashboard/static/app/core/trunks/summary.html
Normal file
@ -0,0 +1,17 @@
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Neutron::Trunk"
|
||||
item="item"
|
||||
property-groups="[
|
||||
['name', 'id', 'project_id'],
|
||||
['created_at', 'updated_at', 'description']]">
|
||||
</hz-resource-property-list>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<dl>
|
||||
<div ng-repeat="(key, value) in item.extras">
|
||||
<dt>{$ key $}</dt>
|
||||
<dd>{$ value $}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
160
openstack_dashboard/static/app/core/trunks/trunks.module.js
Normal file
160
openstack_dashboard/static/app/core/trunks/trunks.module.js
Normal file
@ -0,0 +1,160 @@
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @description
|
||||
* Provides all of the services and widgets required
|
||||
* to support and display trunks related content.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.trunks', [
|
||||
'ngRoute',
|
||||
'horizon.framework.conf',
|
||||
'horizon.app.core'
|
||||
])
|
||||
.constant('horizon.app.core.trunks.resourceType', 'OS::Neutron::Trunk')
|
||||
.run(run)
|
||||
.config(config);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.app.core.trunks.basePath',
|
||||
'horizon.app.core.trunks.service',
|
||||
'horizon.app.core.trunks.resourceType'
|
||||
];
|
||||
|
||||
function run(registry,
|
||||
gettext,
|
||||
basePath,
|
||||
trunksService,
|
||||
trunkResourceType) {
|
||||
registry.getResourceType(trunkResourceType)
|
||||
.setNames(gettext('Trunk'), gettext('Trunks'))
|
||||
.setSummaryTemplateUrl(basePath + 'summary.html')
|
||||
.setProperties(trunkProperties())
|
||||
.setListFunction(trunksService.getTrunksPromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name_or_id',
|
||||
priority: 1,
|
||||
sortDefault: true
|
||||
})
|
||||
.append({
|
||||
id: 'port_id',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'subport_count',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'admin_state',
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'status',
|
||||
priority: 1
|
||||
});
|
||||
|
||||
/**
|
||||
* Filtering - client-side MagicSearch
|
||||
* all facets for trunks table
|
||||
*/
|
||||
registry.getResourceType(trunkResourceType).filterFacets
|
||||
.append({
|
||||
label: gettext('Name'),
|
||||
name: 'name',
|
||||
singleton: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Parent Port'),
|
||||
name: 'port_id',
|
||||
singleton: true
|
||||
})
|
||||
.append({
|
||||
label: gettext('Status'),
|
||||
name: 'status',
|
||||
singleton: true,
|
||||
options: [
|
||||
{label: gettext('Active'), key: 'ACTIVE'},
|
||||
{label: gettext('Down'), key: 'DOWN'},
|
||||
{label: gettext('Build'), key: 'BUILD'},
|
||||
{label: gettext('Degraded'), key: 'DEGRADED'},
|
||||
{label: gettext('Error'), key: 'ERROR'}
|
||||
]
|
||||
})
|
||||
.append({
|
||||
label: gettext('Admin State'),
|
||||
name: 'admin_state_up',
|
||||
singleton: true,
|
||||
options: [
|
||||
{label: gettext('Up'), key: 'true'},
|
||||
{label: gettext('Down'), key: 'false'}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @name trunkProperties
|
||||
* @description resource properties for trunk module
|
||||
*/
|
||||
function trunkProperties() {
|
||||
return {
|
||||
admin_state: gettext('Admin State'),
|
||||
created_at: gettext('Created at'),
|
||||
description: gettext('Description'),
|
||||
id: gettext('ID'),
|
||||
name: gettext('Name'),
|
||||
name_or_id: gettext('Name'),
|
||||
port_id: gettext('Parent Port'),
|
||||
project_id: gettext('Project ID'),
|
||||
status: gettext('Status'),
|
||||
subport_count: gettext('Subport Count'),
|
||||
updated_at: gettext('Updated at')
|
||||
};
|
||||
}
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider',
|
||||
'$routeProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name config
|
||||
* @param {Object} $provide
|
||||
* @param {Object} $windowProvider
|
||||
* @param {Object} $routeProvider
|
||||
* @description Routes used by this module.
|
||||
* @returns {undefined} Returns nothing
|
||||
*/
|
||||
function config($provide, $windowProvider, $routeProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'app/core/trunks/';
|
||||
$provide.constant('horizon.app.core.trunks.basePath', path);
|
||||
|
||||
$routeProvider.when('/project/trunks', {
|
||||
templateUrl: path + 'panel.html'
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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('horizon.app.core.trunks', function () {
|
||||
it('should exist', function () {
|
||||
expect(angular.module('horizon.app.core.trunks')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('loading the trunk module', function () {
|
||||
var registry;
|
||||
|
||||
beforeEach(module('horizon.app.core.trunks'));
|
||||
beforeEach(inject(function($injector) {
|
||||
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
|
||||
}));
|
||||
|
||||
it('registers names', function() {
|
||||
expect(registry.getResourceType('OS::Neutron::Trunk').getName()).toBe("Trunks");
|
||||
});
|
||||
|
||||
it('should set facets for search', function () {
|
||||
var names = registry.getResourceType('OS::Neutron::Trunk').filterFacets
|
||||
.map(getName);
|
||||
expect(names).toContain('name');
|
||||
expect(names).toContain('port_id');
|
||||
expect(names).toContain('status');
|
||||
expect(names).toContain('admin_state_up');
|
||||
|
||||
function getName(x) {
|
||||
return x.name;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
61
openstack_dashboard/static/app/core/trunks/trunks.service.js
Normal file
61
openstack_dashboard/static/app/core/trunks/trunks.service.js
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* 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')
|
||||
.factory('horizon.app.core.trunks.service', trunksService);
|
||||
|
||||
trunksService.$inject = [
|
||||
'horizon.app.core.openstack-service-api.neutron',
|
||||
'horizon.app.core.openstack-service-api.userSession'
|
||||
];
|
||||
|
||||
/*
|
||||
* @ngdoc factory
|
||||
* @name horizon.app.core.trunks.service
|
||||
*
|
||||
* @description
|
||||
* This service provides functions that are used through the Trunks
|
||||
* features. These are primarily used in the module registrations
|
||||
* but do not need to be restricted to such use. Each exposed function
|
||||
* is documented below.
|
||||
*/
|
||||
function trunksService(neutron, userSession) {
|
||||
|
||||
return {
|
||||
getTrunksPromise: getTrunksPromise
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getTrunksPromise
|
||||
* @description
|
||||
* Given filter/query parameters, returns a promise for the matching
|
||||
* trunks. This is used in displaying lists of Trunks.
|
||||
*/
|
||||
function getTrunksPromise(params) {
|
||||
return userSession.get().then(getTrunksForProject);
|
||||
|
||||
function getTrunksForProject(userSession) {
|
||||
params.project_id = userSession.project_id;
|
||||
return neutron.getTrunks(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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('trunks service', function() {
|
||||
var service;
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.app.core.trunks'));
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.app.core.trunks.service');
|
||||
}));
|
||||
|
||||
describe('getTrunksPromise', function() {
|
||||
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
|
||||
var neutron = $injector.get('horizon.app.core.openstack-service-api.neutron');
|
||||
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
|
||||
var deferred = $q.defer();
|
||||
var deferredSession = $q.defer();
|
||||
spyOn(neutron, 'getTrunks').and.returnValue(deferred.promise);
|
||||
spyOn(session, 'get').and.returnValue(deferredSession.promise);
|
||||
var result = service.getTrunksPromise({});
|
||||
deferred.resolve({data: {items: [{id: 1, updated_at: 'Apr10'}]}});
|
||||
deferredSession.resolve({project_id: '42'});
|
||||
$timeout.flush();
|
||||
expect(neutron.getTrunks).toHaveBeenCalled();
|
||||
expect(result.$$state.value.data.items[0].updated_at).toBe('Apr10');
|
||||
expect(result.$$state.value.data.items[0].id).toBe(1);
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -78,6 +78,8 @@
|
||||
.setNames(gettext('Floating IP'), gettext('Floating IPs'));
|
||||
registry.getResourceType('OS::Neutron::SecurityGroup')
|
||||
.setNames(gettext('Security Group'), gettext('Security Groups'));
|
||||
registry.getResourceType('OS::Neutron::Trunk')
|
||||
.setNames(gettext('Trunk'), gettext('Trunks'));
|
||||
registry.getResourceType('OS::Keystone::User')
|
||||
.setNames(gettext('User'), gettext('Users'));
|
||||
registry.getResourceType('OS::Keystone::Group')
|
||||
|
@ -159,6 +159,19 @@ class NeutronPortsTestCase(test.TestCase):
|
||||
request, network_id=TEST.api_networks.first().get("id"))
|
||||
|
||||
|
||||
class NeutronTrunksTestCase(test.TestCase):
|
||||
|
||||
@mock.patch.object(neutron.api, 'neutron')
|
||||
def test_get(self, client):
|
||||
request = self.mock_rest_request(GET={})
|
||||
client.trunk_list.return_value = self.trunks.list()
|
||||
response = neutron.Trunks().get(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertItemsCollectionEqual(
|
||||
response,
|
||||
[t.to_dict() for t in self.trunks.list()])
|
||||
|
||||
|
||||
class NeutronExtensionsTestCase(test.TestCase):
|
||||
def setUp(self):
|
||||
super(NeutronExtensionsTestCase, self).setUp()
|
||||
|
@ -415,6 +415,33 @@ class NeutronApiTests(test.APITestCase):
|
||||
|
||||
api.neutron.port_delete(self.request, port_id)
|
||||
|
||||
def test_trunk_list(self):
|
||||
trunks = {'trunks': self.api_trunks.list()}
|
||||
neutron_client = self.stub_neutronclient()
|
||||
neutron_client.list_trunks().AndReturn(trunks)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
ret_val = api.neutron.trunk_list(self.request)
|
||||
for t in ret_val:
|
||||
self.assertIsInstance(t, api.neutron.Trunk)
|
||||
|
||||
def test_trunk_object(self):
|
||||
trunk = self.api_trunks.first().copy()
|
||||
obj = api.neutron.Trunk(trunk)
|
||||
self.assertEqual(0, obj.subport_count)
|
||||
trunk_dict = obj.to_dict()
|
||||
self.assertIsInstance(trunk_dict, dict)
|
||||
self.assertEqual(trunk['name'], trunk_dict['name_or_id'])
|
||||
self.assertEqual(0, trunk_dict['subport_count'])
|
||||
|
||||
trunk['name'] = '' # to test name_or_id
|
||||
trunk['sub_ports'] = [uuidutils.generate_uuid() for i in range(2)]
|
||||
obj = api.neutron.Trunk(trunk)
|
||||
self.assertEqual(2, obj.subport_count)
|
||||
trunk_dict = obj.to_dict()
|
||||
self.assertEqual(obj.name_or_id, trunk_dict['name_or_id'])
|
||||
self.assertEqual(2, trunk_dict['subport_count'])
|
||||
|
||||
def test_router_list(self):
|
||||
routers = {'routers': self.api_routers.list()}
|
||||
|
||||
|
@ -278,6 +278,11 @@ TEST_GLOBAL_MOCKS_ON_PANELS = {
|
||||
'.firewalls.panel.Firewall.can_access'),
|
||||
'return_value': True,
|
||||
},
|
||||
'trunk': {
|
||||
'method': ('openstack_dashboard.dashboards.project'
|
||||
'.trunks.panel.Trunks.can_access'),
|
||||
'return_value': True,
|
||||
},
|
||||
'vpn': {
|
||||
'method': ('openstack_dashboard.dashboards.project'
|
||||
'.vpn.panel.VPN.can_access'),
|
||||
|
@ -31,6 +31,7 @@ def data(TEST):
|
||||
TEST.subnets = utils.TestDataContainer()
|
||||
TEST.subnetpools = utils.TestDataContainer()
|
||||
TEST.ports = utils.TestDataContainer()
|
||||
TEST.trunks = utils.TestDataContainer()
|
||||
TEST.routers = utils.TestDataContainer()
|
||||
TEST.routers_with_rules = utils.TestDataContainer()
|
||||
TEST.routers_with_routes = utils.TestDataContainer()
|
||||
@ -59,6 +60,7 @@ def data(TEST):
|
||||
TEST.api_subnets = utils.TestDataContainer()
|
||||
TEST.api_subnetpools = utils.TestDataContainer()
|
||||
TEST.api_ports = utils.TestDataContainer()
|
||||
TEST.api_trunks = utils.TestDataContainer()
|
||||
TEST.api_routers = utils.TestDataContainer()
|
||||
TEST.api_routers_with_routes = utils.TestDataContainer()
|
||||
TEST.api_floating_ips = utils.TestDataContainer()
|
||||
@ -327,6 +329,18 @@ def data(TEST):
|
||||
TEST.api_ports.add(port_dict)
|
||||
TEST.ports.add(neutron.Port(port_dict))
|
||||
|
||||
trunk_dict = {'status': 'UP',
|
||||
'sub_ports': [],
|
||||
'name': 'trunk1',
|
||||
'admin_state_up': True,
|
||||
'tenant_id': '1',
|
||||
'project_id': '1',
|
||||
'port_id': '895d375c-1447-11e7-a52f-f7f280bbc809',
|
||||
'id': '94fcb9e8-1447-11e7-bed6-8b8c4ac74491'}
|
||||
|
||||
TEST.api_trunks.add(trunk_dict)
|
||||
TEST.trunks.add(neutron.Trunk(trunk_dict))
|
||||
|
||||
router_dict = {'id': '279989f7-54bb-41d9-ba42-0d61f12fda61',
|
||||
'name': 'router1',
|
||||
'status': 'ACTIVE',
|
||||
@ -574,11 +588,15 @@ def data(TEST):
|
||||
extension_5 = {"name": "HA Router extension",
|
||||
"alias": "l3-ha",
|
||||
"description": "Add HA capability to routers."}
|
||||
extension_6 = {"name": "Trunks",
|
||||
"alias": "trunk",
|
||||
"description": "Provides support for trunk ports."}
|
||||
TEST.api_extensions.add(extension_1)
|
||||
TEST.api_extensions.add(extension_2)
|
||||
TEST.api_extensions.add(extension_3)
|
||||
TEST.api_extensions.add(extension_4)
|
||||
TEST.api_extensions.add(extension_5)
|
||||
TEST.api_extensions.add(extension_6)
|
||||
|
||||
# 1st agent.
|
||||
agent_dict = {"binary": "neutron-openvswitch-agent",
|
||||
|
Loading…
Reference in New Issue
Block a user