Remove Container panel and action
According to decisions that Magnum becomes COE Management Service, Magnum-UI should remove Container panel and actions that is for Docker Swarm container manipulations. This patch removes following items. - Container views (table and detail) - Container actions (create and delete) - Create Container action from bay table view and bay detail view Change-Id: Ia18e9fa57e0460b9b1a8b473a005d31cb4acc5ca Implements: blueprint remove-container-panel
This commit is contained in:
parent
fcde926b85
commit
bf4897e6f6
@ -51,7 +51,6 @@ And enable it in Horizon::
|
||||
cp ../magnum-ui/enabled/_50_project_containers_panelgroup.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_51_project_containers_bays_panel.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_52_project_containers_baymodels_panel.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_53_project_containers_containers_panel.py openstack_dashboard/local/enabled
|
||||
|
||||
To run horizon with the newly enabled Magnum UI plugin run::
|
||||
|
||||
|
@ -8,8 +8,16 @@ Magnum Dashboard
|
||||
* Source: http://git.openstack.org/cgit/openstack/magnum-ui
|
||||
* Bugs: http://bugs.launchpad.net/magnum-ui
|
||||
|
||||
Installation instructions
|
||||
=========================
|
||||
Enabling in DevStack
|
||||
====================
|
||||
|
||||
Add this repo as an external repository into your ``local.conf`` file::
|
||||
|
||||
[[local|localrc]]
|
||||
enable_plugin magnum-ui https://github.com/openstack/magnum-ui
|
||||
|
||||
Manual Installation
|
||||
===================
|
||||
|
||||
Begin by cloning the Horizon and Magnum UI repositories::
|
||||
|
||||
@ -34,7 +42,6 @@ editor. You will want to customize several settings:
|
||||
environment. (They should be correct unless you modified your
|
||||
OpenStack server to change them.)
|
||||
|
||||
|
||||
Install Magnum UI with all dependencies in your virtual environment::
|
||||
|
||||
tools/with_venv.sh pip install -e ../magnum-ui/
|
||||
@ -44,7 +51,13 @@ And enable it in Horizon::
|
||||
cp ../magnum-ui/enabled/_50_project_containers_panelgroup.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_51_project_containers_bays_panel.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_52_project_containers_baymodels_panel.py openstack_dashboard/local/enabled
|
||||
cp ../magnum-ui/enabled/_53_project_containers_containers_panel.py openstack_dashboard/local/enabled
|
||||
|
||||
To run horizon with the newly enabled Magnum UI plugin run::
|
||||
|
||||
./run_tests.sh --runserver 0.0.0.0:8080
|
||||
|
||||
to have the application start on port 8080 and the horizon dashboard will be
|
||||
available in your browser at http://localhost:8080/
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
@ -1,23 +0,0 @@
|
||||
# Copyright 2015 NEC Corporation, Inc.
|
||||
#
|
||||
# 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 = 'bays.containers'
|
||||
# The slug of the panel group the PANEL is associated with.
|
||||
PANEL_GROUP = 'containers'
|
||||
# The slug of the dashboard the PANEL associated with. Required.
|
||||
PANEL_DASHBOARD = 'project'
|
||||
|
||||
# Python panel class of the PANEL to be added.
|
||||
ADD_PANEL = 'magnum_ui.content.bays.containers.panel.Containers'
|
@ -112,49 +112,3 @@ def bay_list(request, limit=None, marker=None, sort_key=None,
|
||||
|
||||
def bay_show(request, id):
|
||||
return magnumclient(request).bays.get(id)
|
||||
|
||||
|
||||
def container_create(request, bay_uuid, **kwargs):
|
||||
"""Creates a container object
|
||||
|
||||
:param request: Request context
|
||||
:param bay_uuid: ID of a bay (Required)
|
||||
:param kwargs: Image ID, Name, Command, Memory
|
||||
:returns: Container object
|
||||
"""
|
||||
return magnumclient(request).containers.create(bay_uuid=bay_uuid, **kwargs)
|
||||
|
||||
|
||||
def container_delete(request, id):
|
||||
"""Deletes a container
|
||||
|
||||
:param request: Request context
|
||||
:param id: The ID of the container to delete
|
||||
"""
|
||||
magnumclient(request).containers.delete(id)
|
||||
|
||||
|
||||
def container_list(request, marker=None, limit=None, sort_key=None,
|
||||
sort_dir=None, detail=False):
|
||||
"""Lists all containers
|
||||
|
||||
:param request: Request context
|
||||
:param marker: Optional, ID of last container in previous results
|
||||
:param limit: '==0' return all, '> 0' specifies max, None respects max
|
||||
imposed by Magnum API
|
||||
:param sort_key: Optional, key to sort by
|
||||
:param sort_dir: Optional, direction of sorting ('asc' or 'desc')
|
||||
:param detail: Optional, boolean, return detailed info about containers
|
||||
"""
|
||||
return magnumclient(request).containers.list(
|
||||
marker=marker, limit=limit, sort_key=sort_key, sort_dir=sort_dir,
|
||||
detail=detail)
|
||||
|
||||
|
||||
def container_show(request, id):
|
||||
"""Get an individual container
|
||||
|
||||
:param request: Request context
|
||||
:param id: ID of the container to get
|
||||
"""
|
||||
return magnumclient(request).containers.get(id)
|
||||
|
@ -122,50 +122,3 @@ class Bays(generic.View):
|
||||
return rest_utils.CreatedResponse(
|
||||
'/api/containers/bay/%s' % new_bay.uuid,
|
||||
new_bay.to_dict())
|
||||
|
||||
|
||||
@urls.register
|
||||
class Container(generic.View):
|
||||
"""API for retrieving a single container"""
|
||||
url_regex = r'containers/containers/(?P<container_id>[^/]+)$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request, container_id):
|
||||
"""Get a specific container"""
|
||||
return magnum.container_show(request, container_id).to_dict()
|
||||
|
||||
|
||||
@urls.register
|
||||
class Containers(generic.View):
|
||||
"""API for Magnum Containers"""
|
||||
url_regex = r'containers/containers/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get a list of the Containers for a project.
|
||||
|
||||
The returned result is an object with property 'items' and each
|
||||
item under this is a Container.
|
||||
"""
|
||||
result = magnum.container_list(request)
|
||||
return {'items': [change_to_id(n.to_dict()) for n in result]}
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def delete(self, request):
|
||||
"""Delete one or more Containers by ID.
|
||||
|
||||
Returns HTTP 204 (no content) on successful deletion.
|
||||
"""
|
||||
for container_id in request.DATA:
|
||||
magnum.container_delete(request, container_id)
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def post(self, request):
|
||||
"""Create a new Container.
|
||||
|
||||
Returns the new Container object on success.
|
||||
"""
|
||||
container = magnum.container_create(request, **request.DATA)
|
||||
return rest_utils.CreatedResponse(
|
||||
'/api/containers/container/%s' % container.uuid,
|
||||
container.to_dict())
|
||||
|
@ -1,21 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems
|
||||
#
|
||||
# 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 Containers(horizon.Panel):
|
||||
name = _("Containers")
|
||||
slug = "bays.containers"
|
@ -1,36 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems, Inc.
|
||||
#
|
||||
# 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.core.urlresolvers import reverse
|
||||
# import horizon
|
||||
# from magnum_ui.containers.containers.panel import Containers
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class ContainerTests(test.TestCase):
|
||||
def test_me(self):
|
||||
self.assertTrue(1 + 1 == 2)
|
||||
|
||||
# FIXME(shu-mutou): this tests seems not to work in new Horizon's plugin
|
||||
# registration system
|
||||
# def test_registration(self):
|
||||
# dashboard = horizon.get_dashboard('project')
|
||||
# registered_panel = dashboard.get_panel('containers.containers')
|
||||
# self.assertEqual(registered_panel.slug, Containers.slug)
|
||||
|
||||
# def test_index(self):
|
||||
# index = reverse('horizon:bays:containers:index')
|
||||
# res = self.client.get(index)
|
||||
# self.assertTemplateUsed(
|
||||
# res, 'project/bays/containers/index.html')
|
@ -1,22 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems, Inc.
|
||||
#
|
||||
# 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 magnum_ui.content.bays.containers import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^[0-9a-f\-]{36}$', views.IndexView.as_view(), name='detail'),
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
]
|
@ -1,19 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems
|
||||
#
|
||||
# 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 horizon import views
|
||||
|
||||
|
||||
class IndexView(views.APIView):
|
||||
template_name = 'bays.containers/index.html'
|
@ -12,14 +12,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from django.conf.urls import include
|
||||
from django.conf.urls import url
|
||||
from magnum_ui.content.bays.containers import urls as containers_urls
|
||||
from magnum_ui.content.bays.views import IndexView
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^containers/', include(containers_urls, namespace='containers')),
|
||||
url(r'^[0-9a-f\-]{36}$', IndexView.as_view(), name='detail'),
|
||||
url(r'^$', IndexView.as_view(), name='index'),
|
||||
]
|
||||
|
@ -30,7 +30,6 @@
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.dashboard.containers.bays.create.service',
|
||||
'horizon.dashboard.containers.bays.delete.service',
|
||||
'horizon.dashboard.containers.containers.create.service',
|
||||
'horizon.dashboard.containers.bays.resourceType',
|
||||
];
|
||||
|
||||
@ -39,18 +38,10 @@
|
||||
gettext,
|
||||
createBayService,
|
||||
deleteBayService,
|
||||
createContainerService,
|
||||
resourceType)
|
||||
{
|
||||
var bayResourceType = registry.getResourceType(resourceType);
|
||||
bayResourceType.itemActions
|
||||
.append({
|
||||
id: 'createContainerAction',
|
||||
service: createContainerService,
|
||||
template: {
|
||||
text: gettext('Create Container')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'deleteBayAction',
|
||||
service: deleteBayService,
|
||||
|
@ -27,13 +27,12 @@
|
||||
'$routeParams',
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.dashboard.containers.bays.events',
|
||||
'horizon.dashboard.containers.containers.events',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.containers.bays.resourceType'
|
||||
];
|
||||
|
||||
function BayDetailController(
|
||||
$scope, $window, $location, $routeParams, magnum, events, containerEvents, registry, bayResourceType
|
||||
$scope, $window, $location, $routeParams, magnum, events, registry, bayResourceType
|
||||
) {
|
||||
var ctrl = this;
|
||||
ctrl.bay = {};
|
||||
@ -43,7 +42,6 @@
|
||||
var bayId = $routeParams.bayId;
|
||||
|
||||
var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess);
|
||||
var createContainerWatcher = $scope.$on(containerEvents.CREATE_SUCCESS, onCreateContainerSuccess);
|
||||
|
||||
$scope.$on('$destroy', destroy);
|
||||
|
||||
@ -70,14 +68,8 @@
|
||||
$location.path("/project/bays");
|
||||
}
|
||||
|
||||
function onCreateContainerSuccess(e, createdItem) {
|
||||
e.stopPropagation();
|
||||
$location.path("/project/bays/containers");
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
deleteWatcher();
|
||||
createContainerWatcher();
|
||||
}
|
||||
}
|
||||
})();
|
@ -34,12 +34,11 @@
|
||||
'$location',
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.dashboard.containers.bays.events',
|
||||
'horizon.dashboard.containers.containers.events',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.containers.bays.resourceType'
|
||||
];
|
||||
|
||||
function containersBaysTableController($scope, $location, magnum, events, containerEvents, registry, bayResourceType) {
|
||||
function containersBaysTableController($scope, $location, magnum, events, registry, bayResourceType) {
|
||||
var ctrl = this;
|
||||
ctrl.bays = [];
|
||||
ctrl.baysSrc = [];
|
||||
@ -78,7 +77,6 @@
|
||||
];
|
||||
|
||||
var createWatcher = $scope.$on(events.CREATE_SUCCESS, onCreateSuccess);
|
||||
var createContainerWatcher = $scope.$on(containerEvents.CREATE_SUCCESS, onCreateContainerSuccess);
|
||||
var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess);
|
||||
|
||||
$scope.$on('$destroy', destroy);
|
||||
@ -99,11 +97,6 @@
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function onCreateContainerSuccess(e, createdItem) {
|
||||
e.stopPropagation();
|
||||
$location.path("/project/bays/containers");
|
||||
}
|
||||
|
||||
function onDeleteSuccess(e, removedIds) {
|
||||
ctrl.baysSrc = difference(ctrl.baysSrc, removedIds, 'id');
|
||||
e.stopPropagation();
|
||||
@ -125,7 +118,6 @@
|
||||
|
||||
function destroy() {
|
||||
createWatcher();
|
||||
createContainerWatcher();
|
||||
deleteWatcher();
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
.module('horizon.dashboard.containers', [
|
||||
'horizon.dashboard.containers.bays',
|
||||
'horizon.dashboard.containers.baymodels',
|
||||
'horizon.dashboard.containers.containers',
|
||||
'ngRoute'
|
||||
])
|
||||
.config(config)
|
||||
@ -41,12 +40,6 @@
|
||||
$provide.constant('horizon.dashboard.containers.basePath', path);
|
||||
|
||||
$routeProvider
|
||||
.when('/project/bays/containers', {
|
||||
templateUrl: path + 'containers/table/table.html'
|
||||
})
|
||||
.when('/project/bays/containers/:containerId', {
|
||||
templateUrl: path + 'containers/detail/detail.html'
|
||||
})
|
||||
.when('/project/baymodels', {
|
||||
templateUrl: path + 'baymodels/table/table.html'
|
||||
})
|
||||
|
@ -1,6 +1,5 @@
|
||||
@import "baymodels/baymodels";
|
||||
@import "bays/bays";
|
||||
@import "containers/containers";
|
||||
|
||||
.table > thead > .action-row > th > actions {
|
||||
float: right;
|
||||
|
@ -1,73 +0,0 @@
|
||||
/**
|
||||
* 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.containers.containers.actions
|
||||
*
|
||||
* @description
|
||||
* Provides all of the actions for containers.
|
||||
*/
|
||||
angular.module('horizon.dashboard.containers.containers.actions', ['horizon.framework', 'horizon.dashboard.containers'])
|
||||
.run(registerContainerActions);
|
||||
|
||||
registerContainerActions.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.dashboard.containers.containers.create.service',
|
||||
'horizon.dashboard.containers.containers.delete.service',
|
||||
'horizon.dashboard.containers.containers.resourceType',
|
||||
];
|
||||
|
||||
function registerContainerActions(
|
||||
registry,
|
||||
gettext,
|
||||
createContainerService,
|
||||
deleteContainerService,
|
||||
resourceType)
|
||||
{
|
||||
var containerResourceType = registry.getResourceType(resourceType);
|
||||
containerResourceType.itemActions
|
||||
.append({
|
||||
id: 'deleteContainerAction',
|
||||
service: deleteContainerService,
|
||||
template: {
|
||||
type: 'delete',
|
||||
text: gettext('Delete Container')
|
||||
}
|
||||
});
|
||||
|
||||
containerResourceType.batchActions
|
||||
.append({
|
||||
id: 'createContainerAction',
|
||||
service: createContainerService,
|
||||
template: {
|
||||
type: 'create',
|
||||
text: gettext('Create Container')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'batchDeleteContainerAction',
|
||||
service: deleteContainerService,
|
||||
template: {
|
||||
type: 'delete-selected',
|
||||
text: gettext('Delete Containers')
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -1,46 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 Cisco Systems, Inc.
|
||||
*
|
||||
* 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.containers.containers
|
||||
* @ngModule
|
||||
*
|
||||
* @description
|
||||
* Provides all the services and widgets require to display the containers
|
||||
* panel
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers', ['horizon.dashboard.containers.containers.actions'])
|
||||
.constant('horizon.dashboard.containers.containers.events', events())
|
||||
.constant('horizon.dashboard.containers.containers.resourceType', 'OS::Magnum::Container');
|
||||
|
||||
/**
|
||||
* @ngdoc constant
|
||||
* @name horizon.dashboard.containers.containers.events
|
||||
* @description A list of events used by Containers
|
||||
*/
|
||||
function events() {
|
||||
return {
|
||||
CREATE_SUCCESS: 'horizon.dashboard.containers.containers.CREATE_SUCCESS',
|
||||
DELETE_SUCCESS: 'horizon.dashboard.containers.containers.DELETE_SUCCESS'
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 Cisco Systems, Inc.
|
||||
*
|
||||
* 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.dashboard.containers.containers', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('horizon.dashboard.containers.containers')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 Cisco Systems, Inc.
|
||||
*
|
||||
* 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.containers.containers')
|
||||
.factory('horizon.dashboard.containers.containers.containerModel', containerModel);
|
||||
|
||||
containerModel.$inject = [
|
||||
'horizon.app.core.openstack-service-api.magnum'
|
||||
];
|
||||
|
||||
function containerModel(magnum) {
|
||||
var model = {
|
||||
newContainerSpec: {},
|
||||
|
||||
// API methods
|
||||
init: init,
|
||||
createContainer: createContainer
|
||||
};
|
||||
|
||||
function initNewContainerSpec() {
|
||||
model.newContainerSpec = {
|
||||
name: null,
|
||||
bay_uuid: null,
|
||||
image: null,
|
||||
memory: null,
|
||||
memory_size: null,
|
||||
memory_unit: "m",
|
||||
command: null
|
||||
};
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Reset the new Bay spec
|
||||
initNewContainerSpec();
|
||||
}
|
||||
|
||||
function createContainer() {
|
||||
var finalSpec = angular.copy(model.newContainerSpec);
|
||||
|
||||
cleanNullProperties(finalSpec);
|
||||
|
||||
return magnum.createContainer(finalSpec);
|
||||
}
|
||||
|
||||
function cleanNullProperties(finalSpec) {
|
||||
// Initially clean fields that don't have any value.
|
||||
for (var key in finalSpec) {
|
||||
if (finalSpec.hasOwnProperty(key) && finalSpec[key] === null
|
||||
|| key === "memory_size" || key === "memory_unit") {
|
||||
delete finalSpec[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
})();
|
@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 Cisco Systems, Inc.
|
||||
*
|
||||
* 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.containers.containers')
|
||||
.factory('horizon.dashboard.containers.containers.workflow', containerWorkflow);
|
||||
|
||||
containerWorkflow.$inject = [
|
||||
'horizon.dashboard.containers.basePath',
|
||||
'horizon.app.core.workflow.factory',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function containerWorkflow(basePath, dashboardWorkflow, gettext) {
|
||||
return dashboardWorkflow({
|
||||
title: gettext('Create Container'),
|
||||
|
||||
steps: [
|
||||
{
|
||||
title: gettext('Info'),
|
||||
templateUrl: basePath + 'containers/create/info/info.html',
|
||||
helpUrl: basePath + 'containers/create/info/info.help.html',
|
||||
formName: 'containerInfoForm'
|
||||
},
|
||||
{
|
||||
title: gettext('Spec'),
|
||||
templateUrl: basePath + 'containers/create/spec/spec.html',
|
||||
helpUrl: basePath + 'containers/create/spec/spec.help.html',
|
||||
formName: 'containerSpecForm'
|
||||
}
|
||||
],
|
||||
|
||||
btnText: {
|
||||
finish: gettext('Create')
|
||||
},
|
||||
|
||||
btnIcon: {
|
||||
finish: 'fa fa-check'
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
@ -1,90 +0,0 @@
|
||||
/**
|
||||
* 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.containers.containers.create.service
|
||||
* @description Service for the container create modal
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers')
|
||||
.factory('horizon.dashboard.containers.containers.create.service', createService);
|
||||
|
||||
createService.$inject = [
|
||||
'horizon.dashboard.containers.containers.containerModel',
|
||||
'horizon.framework.widgets.modal.wizard-modal.service',
|
||||
'horizon.framework.widgets.toast.service',
|
||||
'horizon.dashboard.containers.containers.workflow',
|
||||
'horizon.dashboard.containers.containers.events',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.framework.util.q.extensions'
|
||||
];
|
||||
|
||||
function createService(
|
||||
model, wizardModalService, toast, createWorkflow, events, policy, gettext, $qExtensions
|
||||
) {
|
||||
|
||||
var scope;
|
||||
var message = {
|
||||
success: gettext('Container %s was successfully created.')
|
||||
};
|
||||
|
||||
var service = {
|
||||
initScope: initScope,
|
||||
perform: perform,
|
||||
allowed: allowed
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
function initScope($scope) {
|
||||
scope = $scope;
|
||||
|
||||
scope.workflow = createWorkflow;
|
||||
scope.model = model;
|
||||
scope.$on('$destroy', function() {
|
||||
});
|
||||
}
|
||||
|
||||
function perform(selected) {
|
||||
scope.model.init();
|
||||
scope.selected = selected;
|
||||
wizardModalService.modal({
|
||||
scope: scope,
|
||||
workflow: createWorkflow,
|
||||
submit: submit
|
||||
});
|
||||
}
|
||||
|
||||
function allowed(selected) {
|
||||
return $qExtensions.booleanAsPromise(true);
|
||||
}
|
||||
|
||||
function submit(){
|
||||
return model.createContainer().then(success);
|
||||
}
|
||||
|
||||
function success(response) {
|
||||
response.data.id = response.data.uuid;
|
||||
toast.add('success', interpolate(message.success, [response.data.id]));
|
||||
scope.$emit(events.CREATE_SUCCESS, response.data);
|
||||
}
|
||||
}
|
||||
})();
|
@ -1,83 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 NEC Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name createContainerInfoController
|
||||
* @ngController
|
||||
*
|
||||
* @description
|
||||
* Controller for the container info step in create workflow
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers')
|
||||
.controller('createContainerInfoController', createContainerInfoController);
|
||||
|
||||
createContainerInfoController.$inject = [
|
||||
'$q',
|
||||
'$scope',
|
||||
'horizon.dashboard.containers.basePath',
|
||||
'horizon.app.core.openstack-service-api.magnum'
|
||||
];
|
||||
|
||||
function createContainerInfoController($q, $scope, basePath, magnum) {
|
||||
var ctrl = this;
|
||||
ctrl.bays = [{id:"", name: gettext("Choose a Bay")}];
|
||||
$scope.model.newContainerSpec.bay_uuid = "";
|
||||
$scope.baydetail = {
|
||||
name: "",
|
||||
id: "",
|
||||
baymodel: "",
|
||||
master_count: "",
|
||||
node_count: "",
|
||||
discovery_url: "",
|
||||
timeout: ""
|
||||
};
|
||||
|
||||
$scope.changeBay = function(){
|
||||
angular.forEach(ctrl.bays, function(bay, idx){
|
||||
if($scope.model.newContainerSpec.bay_uuid === bay.id){
|
||||
$("#bay_detail").show();
|
||||
$("#bay_detail_none").hide();
|
||||
$scope.baydetail.name = bay.name;
|
||||
$scope.baydetail.id = bay.id;
|
||||
$scope.baydetail.baymodel_id = bay.baymodel_id;
|
||||
$scope.baydetail.master_count = bay.master_count;
|
||||
$scope.baydetail.node_count = bay.node_count;
|
||||
$scope.baydetail.discovery_url = bay.discovery_url;
|
||||
$scope.baydetail.timeout = bay.timeout;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
function init() {
|
||||
magnum.getBays({paginate: false}).success(onGetBays);
|
||||
}
|
||||
|
||||
function onGetBays(response) {
|
||||
Array.prototype.push.apply(ctrl.bays, response.items);
|
||||
if($scope.selected instanceof Object){
|
||||
$scope.model.newContainerSpec.bay_uuid = $scope.selected.id;
|
||||
$scope.changeBay();
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
@ -1 +0,0 @@
|
||||
<p translate>Specify container name and choose bay.</p>
|
@ -1,46 +0,0 @@
|
||||
<div ng-controller="createContainerInfoController as ctrl">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-name" translate>
|
||||
Container Name
|
||||
</label>
|
||||
<input name="container-name" type="text" class="form-control" id="container-name"
|
||||
ng-model="model.newContainerSpec.name"
|
||||
placeholder="{$ 'Name of the container to create.'|translate $}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-bay">
|
||||
<translate>Bay</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<select class="form-control" name="container-bay" id="container-bay"
|
||||
ng-model="model.newContainerSpec.bay_uuid"
|
||||
ng-required="true"
|
||||
ng-options="bay.id as bay.name|noName for bay in ctrl.bays"
|
||||
ng-change="changeBay()">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="detail" ng-show="model.newContainerSpec.bay_uuid">
|
||||
<span translate class="h4">Bay Detail</span>
|
||||
<dl class="dl-horizontal">
|
||||
<dt translate>Name</dt>
|
||||
<dd><a ng-href="project/bays/{$ baydetail.id $}" ng-click="cancel()">
|
||||
{$ baydetail.name|noName $}
|
||||
</a></dd>
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ baydetail.id $}</dd>
|
||||
<dt translate>Baymodel ID</dt>
|
||||
<dd>{$ baydetail.baymodel_id $}</dd>
|
||||
<dt translate>Master Count</dt>
|
||||
<dd>{$ baydetail.master_count $}</dd>
|
||||
<dt translate>Node Count</dt>
|
||||
<dd>{$ baydetail.node_count $}</dd>
|
||||
<dt translate>Timeout</dt>
|
||||
<dd>{$ baydetail.timeout $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,61 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 NEC Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name createContainerSpecController
|
||||
* @ngController
|
||||
*
|
||||
* @description
|
||||
* Controller for the container spec step in create workflow
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers')
|
||||
.controller('createContainerSpecController', createContainerSpecController);
|
||||
|
||||
createContainerSpecController.$inject = [
|
||||
'$q',
|
||||
'$scope',
|
||||
'horizon.dashboard.containers.basePath',
|
||||
'horizon.app.core.openstack-service-api.magnum'
|
||||
];
|
||||
|
||||
function createContainerSpecController($q, $scope, basePath, magnum) {
|
||||
var ctrl = this;
|
||||
ctrl.memory_units = [{unit: "b", label: gettext("bytes")},
|
||||
{unit: "k", label: gettext("KB")},
|
||||
{unit: "m", label: gettext("MB")},
|
||||
{unit: "g", label: gettext("GB")}];
|
||||
|
||||
$scope.changeMemory = function(){
|
||||
if($scope.model.newContainerSpec.memory_size > 0){
|
||||
$scope.model.newContainerSpec.memory = $scope.model.newContainerSpec.memory_size + $scope.model.newContainerSpec.memory_unit;
|
||||
}else{
|
||||
$scope.model.newContainerSpec.memory = null;
|
||||
}
|
||||
};
|
||||
$scope.changeMemoryUnit = function(){
|
||||
$scope.changeMemory();
|
||||
};
|
||||
$scope.changeMemorySize = function(){
|
||||
$scope.changeMemory();
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
@ -1 +0,0 @@
|
||||
<p translate>Specify the specs for the container.</p>
|
@ -1,48 +0,0 @@
|
||||
<div ng-controller="createContainerSpecController as ctrl">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-image" translate>
|
||||
<translate>Image</translate>
|
||||
<span class="hz-icon-required fa fa-asterisk"></span>
|
||||
</label>
|
||||
<input name="container-image" type="text" class="form-control" id="container-image"
|
||||
ng-required="true" ng-model="model.newContainerSpec.image"
|
||||
placeholder="{$ 'Name of the container image.'|translate $}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-memory-size" translate>Memory Size</label>
|
||||
<input name="container-memory-size" type="number" min="1"
|
||||
class="form-control" ng-model="model.newContainerSpec.memory_size"
|
||||
placeholder="{$ 'The container memory size.'|translate $}"
|
||||
ng-change="changeMemorySize()" id="container-memory-size">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-memory-unit" translate>Memory Unit</label>
|
||||
<select name="container-memory-unit" id="container-memory-unit"
|
||||
class="form-control" ng-options="mu.unit as mu.label for mu in ctrl.memory_units"
|
||||
ng-model="model.newContainerSpec.memory_unit" ng-change="changeMemoryUnit()">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="container-command" translate>Command</label>
|
||||
<input name="container-command" type="text" class="form-control" id="container-command"
|
||||
ng-model="model.newContainerSpec.command"
|
||||
placeholder="{$ 'Send command to the contaier in a line.'|translate $}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,125 +0,0 @@
|
||||
/**
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use self 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.containers.containers')
|
||||
.factory('horizon.dashboard.containers.containers.delete.service', deleteService);
|
||||
|
||||
deleteService.$inject = [
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.widgets.modal.deleteModalService',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.framework.util.q.extensions',
|
||||
'horizon.dashboard.containers.containers.events'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngDoc factory
|
||||
* @name horizon.dashboard.containers.containers.delete.service
|
||||
*
|
||||
* @Description
|
||||
* Brings up the delete containers confirmation modal dialog.
|
||||
* On submit, delete selected resources.
|
||||
* On cancel, do nothing.
|
||||
*/
|
||||
function deleteService(
|
||||
magnum, policy, deleteModalService, gettext, $qExtensions, events
|
||||
) {
|
||||
var scope;
|
||||
var context = {
|
||||
labels: null,
|
||||
deleteEntity: deleteEntity,
|
||||
successEvent: events.DELETE_SUCCESS
|
||||
};
|
||||
|
||||
var service = {
|
||||
initScope: initScope,
|
||||
allowed: allowed,
|
||||
perform: perform
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
// include this function in your service
|
||||
// if you plan to emit events to the parent controller
|
||||
function initScope($scope) {
|
||||
scope = $scope;
|
||||
}
|
||||
|
||||
function allowed() {
|
||||
return $qExtensions.booleanAsPromise(true);
|
||||
}
|
||||
|
||||
// delete selected resource objects
|
||||
function perform(selected) {
|
||||
if(!selected.hasOwnProperty('id')){
|
||||
// batch (multi)
|
||||
context.labels = labelize(selected.length);
|
||||
$qExtensions.allSettled(selected.map(checkPermission)).then(afterCheck);
|
||||
}else{
|
||||
// row (single)
|
||||
context.labels = labelize(1);
|
||||
deleteModalService.open(scope, [selected], context);
|
||||
}
|
||||
}
|
||||
|
||||
function labelize(count){
|
||||
return {
|
||||
title: ngettext('Confirm Delete Container',
|
||||
'Confirm Delete Containers', count),
|
||||
/* eslint-disable max-len */
|
||||
message: ngettext('You have selected "%s". Please confirm your selection. Deleted container is not recoverable.',
|
||||
'You have selected "%s". Please confirm your selection. Deleted containers are not recoverable.', count),
|
||||
/* eslint-enable max-len */
|
||||
submit: ngettext('Delete Container',
|
||||
'Delete Containers', count),
|
||||
success: ngettext('Deleted Container: %s.',
|
||||
'Deleted Containers: %s.', count),
|
||||
error: ngettext('Unable to delete Container: %s.',
|
||||
'Unable to delete Containers: %s.', count)
|
||||
};
|
||||
}
|
||||
|
||||
// for batch delete
|
||||
function checkPermission(selected) {
|
||||
return {promise: allowed(selected), context: selected};
|
||||
}
|
||||
|
||||
// for batch delete
|
||||
function afterCheck(result){
|
||||
if (result.fail.length > 0) {
|
||||
toast.add('error', getMessage(notAllowedMessage, result.fail));
|
||||
}
|
||||
if (result.pass.length > 0) {
|
||||
deleteModalService.open(scope, result.pass.map(getEntity), context);
|
||||
}
|
||||
}
|
||||
|
||||
// for batch delete
|
||||
function getEntity(result) {
|
||||
return result.context;
|
||||
}
|
||||
|
||||
// call delete REST API
|
||||
function deleteEntity(id){
|
||||
return magnum.deleteContainer(id, true);
|
||||
}
|
||||
}
|
||||
})();
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 NEC Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers')
|
||||
.controller('ContainerDetailController', ContainerDetailController);
|
||||
|
||||
ContainerDetailController.$inject = [
|
||||
'$scope',
|
||||
'$window',
|
||||
'$location',
|
||||
'$routeParams',
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.dashboard.containers.containers.events',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.containers.containers.resourceType'
|
||||
];
|
||||
|
||||
function ContainerDetailController($scope, $window, $location, $routeParams, magnum, events, registry, containerResourceType) {
|
||||
var ctrl = this;
|
||||
ctrl.container = {};
|
||||
ctrl.bay = {};
|
||||
ctrl.baymodel = {};
|
||||
ctrl.containerResource = registry.getResourceType(containerResourceType);
|
||||
|
||||
var containerId = $routeParams.containerId;
|
||||
|
||||
var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess);
|
||||
|
||||
$scope.$on('$destroy', destroy);
|
||||
|
||||
init();
|
||||
|
||||
function init() {
|
||||
registry.initActions(containerResourceType, $scope);
|
||||
// Load the elements that are used in the overview.
|
||||
magnum.getContainer(containerId).success(onGetContainer);
|
||||
}
|
||||
|
||||
function onGetContainer(container) {
|
||||
ctrl.container = container;
|
||||
ctrl.container.id = container.uuid;
|
||||
magnum.getBay(ctrl.container.bay_uuid).success(onGetBay);
|
||||
}
|
||||
|
||||
function onGetBay(bay) {
|
||||
ctrl.bay = bay;
|
||||
magnum.getBaymodel(ctrl.bay.baymodel_id).success(onGetBaymodel);
|
||||
}
|
||||
|
||||
function onGetBaymodel(baymodel) {
|
||||
ctrl.baymodel = baymodel;
|
||||
}
|
||||
|
||||
function onDeleteSuccess(e, removedIds) {
|
||||
e.stopPropagation();
|
||||
$location.path("/project/bays/containers");
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
deleteWatcher();
|
||||
}
|
||||
}
|
||||
})();
|
@ -1,107 +0,0 @@
|
||||
<div class="content" ng-controller="ContainerDetailController as ctrl">
|
||||
<div class="page-header">
|
||||
<ol class="breadcrumb">
|
||||
<li><a ng-href="project/bays/containers" translate>Containers</a></li>
|
||||
<li class="active">{$ ctrl.container.name|noName $}</li>
|
||||
<div class="pull-right">
|
||||
<actions allowed="ctrl.containerResource.itemActions" type="row" item="ctrl.container"></actions>
|
||||
</div>
|
||||
</ol>
|
||||
</div>
|
||||
<tabset>
|
||||
<tab heading="{$ 'Overview' | translate $}">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 translate>Spec</h3>
|
||||
<hr class="header-rule">
|
||||
<dl class="dl-horizontal">
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Image</dt>
|
||||
<dd>{$ ctrl.container.image $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Memory</dt>
|
||||
<dd>{$ ctrl.container.memorysize $} {$ ctrl.container.memoryunit $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Command</dt>
|
||||
<dd>{$ ctrl.container.command $}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 translate>Bay</h3>
|
||||
<hr class="header-rule">
|
||||
<dl class="dl-horizontal">
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Name</dt>
|
||||
<dd><a ng-href="project/bays/{$ ctrl.bay.uuid $}">{$ ctrl.bay.name|noName $}</a></dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ ctrl.bay.uuid $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Status</dt>
|
||||
<dd>{$ ctrl.bay.status $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Master Count</dt>
|
||||
<dd>{$ ctrl.bay.master_count $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Node Count</dt>
|
||||
<dd>{$ ctrl.bay.node_count $}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3 translate>Baymodel</h3>
|
||||
<hr class="header-rule">
|
||||
<dl class="dl-horizontal">
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Name</dt>
|
||||
<dd><a ng-href="project/baymodels/{$ ctrl.baymodel.uuid $}">{$ ctrl.baymodel.name|noName $}</a></dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ ctrl.baymodel.uuid $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>COE</dt>
|
||||
<dd>{$ ctrl.baymodel.coe $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Image ID</dt>
|
||||
<dd>{$ ctrl.baymodel.image_id $}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3 translate>Record Properties</h3>
|
||||
<hr class="header-rule">
|
||||
<dl class="dl-horizontal">
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Created</dt>
|
||||
<dd>{$ ctrl.container.created_at | date:'short' $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Updated</dt>
|
||||
<dd>{$ ctrl.container.updated_at | date:'short' $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ ctrl.container.uuid $}</dd>
|
||||
</div>
|
||||
<div class="{$ propertyClasses $}">
|
||||
<dt translate>Status</dt>
|
||||
<dd>{$ ctrl.container.status $}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</tab>
|
||||
</tabset>
|
||||
</div>
|
@ -1,136 +0,0 @@
|
||||
/**
|
||||
* Copyright 2015 Cisco Systems, Inc.
|
||||
*
|
||||
* 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 containersContainersTableController
|
||||
* @ngController
|
||||
*
|
||||
* @description
|
||||
* Controller for the Magnum containers table
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.containers.containers')
|
||||
.controller('containersContainersTableController', containersContainersTableController);
|
||||
|
||||
containersContainersTableController.$inject = [
|
||||
'$scope',
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.dashboard.containers.containers.events',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.dashboard.containers.containers.resourceType'
|
||||
];
|
||||
|
||||
function containersContainersTableController($scope, magnum, events, registry, containerResourceType) {
|
||||
var ctrl = this;
|
||||
ctrl.containers = [];
|
||||
ctrl.containersSrc = [];
|
||||
ctrl.containerResource = registry.getResourceType(containerResourceType);
|
||||
|
||||
|
||||
/**
|
||||
* Filtering - client-side MagicSearch
|
||||
* all facets for container table
|
||||
*/
|
||||
ctrl.containerFacets = [
|
||||
{
|
||||
'label': gettext('Name'),
|
||||
'name': 'name',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('UUID'),
|
||||
'name': 'id',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('Status'),
|
||||
'name': 'status',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('Bay'),
|
||||
'name': 'bay-uuid',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('Image'),
|
||||
'name': 'image',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('Memory'),
|
||||
'name': 'memory',
|
||||
'singleton': true
|
||||
},
|
||||
{
|
||||
'label': gettext('Command'),
|
||||
'name': 'command',
|
||||
'singleton': true
|
||||
}
|
||||
];
|
||||
|
||||
var createWatcher = $scope.$on(events.CREATE_SUCCESS, onCreateSuccess);
|
||||
var deleteWatcher = $scope.$on(events.DELETE_SUCCESS, onDeleteSuccess);
|
||||
|
||||
$scope.$on('$destroy', destroy);
|
||||
|
||||
init();
|
||||
|
||||
function init() {
|
||||
registry.initActions(containerResourceType, $scope);
|
||||
magnum.getContainers().success(getContainersSuccess);
|
||||
}
|
||||
|
||||
function getContainersSuccess(response) {
|
||||
ctrl.containersSrc = response.items;
|
||||
}
|
||||
|
||||
|
||||
function onCreateSuccess(e, createdItem) {
|
||||
ctrl.containersSrc.push(createdItem);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function onDeleteSuccess(e, removedIds) {
|
||||
ctrl.containersSrc = difference(ctrl.containersSrc, removedIds, 'id');
|
||||
e.stopPropagation();
|
||||
|
||||
// after deleting the items
|
||||
// we need to clear selected items from table controller
|
||||
$scope.$emit('hzTable:clearSelected');
|
||||
}
|
||||
|
||||
function difference(currentList, otherList, key) {
|
||||
return currentList.filter(filter);
|
||||
|
||||
function filter(elem) {
|
||||
return otherList.filter(function filterDeletedItem(deletedItem) {
|
||||
return deletedItem === elem[key];
|
||||
}).length === 0;
|
||||
}
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
createWatcher();
|
||||
deleteWatcher();
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -1,156 +0,0 @@
|
||||
<table ng-controller="containersContainersTableController as table"
|
||||
hz-table ng-cloak
|
||||
st-table="table.containers"
|
||||
st-safe-src="table.containersSrc"
|
||||
default-sort="name"
|
||||
default-sort-reverse="false"
|
||||
class="table table-striped table-rsp table-detail">
|
||||
|
||||
<thead>
|
||||
<!--
|
||||
Table-batch-actions:
|
||||
This is where batch actions like searching, creating, and deleting.
|
||||
-->
|
||||
<tr>
|
||||
<th colspan="100" class="search-header">
|
||||
<hz-magic-search-bar group-classes="input-group-sm" icon-classes="fa-search"
|
||||
filter-facets="table.containerFacets">
|
||||
</hz-magic-search-bar>
|
||||
</th>
|
||||
</tr>
|
||||
<tr class="action-row">
|
||||
<th colspan="100">
|
||||
<actions allowed="table.containerResource.batchActions" type="batch"></actions>
|
||||
</th>
|
||||
</tr>
|
||||
<!--
|
||||
Table-column-headers:
|
||||
The headers for the table columns
|
||||
-->
|
||||
<tr>
|
||||
<th class="multi_select_column">
|
||||
<input type="checkbox" hz-select-all="table.containers">
|
||||
</th>
|
||||
|
||||
<th class="expander"></th>
|
||||
|
||||
<th class="rsp-p1" st-sort="name" st-sort-default translate>
|
||||
Name
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="id" translate>
|
||||
ID
|
||||
</th>
|
||||
|
||||
<th class="rsp-p1" st-sort="status" translate>
|
||||
Status
|
||||
</th>
|
||||
|
||||
<th class="rsp-p3" st-sort="bay" translate>
|
||||
Bay ID
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="image" translate>
|
||||
Image
|
||||
</th>
|
||||
|
||||
<th class="rsp-p3" st-sort="memory" translate>
|
||||
Memory
|
||||
</th>
|
||||
|
||||
<th class="actions_column" translate>
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--
|
||||
Table-rows:
|
||||
This is where we declaratively define the table columns.
|
||||
Include multi_select_column if you want to select all.
|
||||
Include expander if you want to inline details.
|
||||
Include actions_column if you want to perform actions.
|
||||
rsp-p1 rsp-p2 are responsive priority as user resizes window.
|
||||
-->
|
||||
|
||||
<tr ng-repeat-start="c in table.containers track by c.id">
|
||||
|
||||
<td class="multi_select_column">
|
||||
<input type="checkbox"
|
||||
ng-model="tCtrl.selections[c.id].checked"
|
||||
hz-select="c">
|
||||
</td>
|
||||
|
||||
<td class="expander">
|
||||
<i class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
duration="200">
|
||||
</i>
|
||||
</td>
|
||||
|
||||
<td class="rsp-p1"><a ng-href="project/bays/containers/{$ c.id $}">{$ c.name|noName $}</a></td>
|
||||
<td class="rsp-p2">{$ c.id $}</td>
|
||||
<td class="rsp-p1">{$ c.status $}</td>
|
||||
<td class="rsp-p3"><a ng-href="project/bays/{$ c.bay_uuid $}">{$ c.bay_uuid $}</a></td>
|
||||
<td class="rsp-p2">{$ c.image $}</td>
|
||||
<td class="rsp-p3">{$ c.memorysize $} {$ c.memoryunit $}</td>
|
||||
|
||||
<td class="actions_column">
|
||||
<!--
|
||||
Table-row-action-column:
|
||||
Actions taken here applies to a single item/row.
|
||||
-->
|
||||
<actions allowed="table.containerResource.itemActions" type="row" item="c"></actions>
|
||||
</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-xs-5">
|
||||
<dt translate>ID</dt>
|
||||
<dd>{$ c.id $}</dd>
|
||||
</dl>
|
||||
<dl class="col-xs-5">
|
||||
<dt translate>Image</dt>
|
||||
<dd>{$ c.image $}</dd>
|
||||
</dl>
|
||||
</span>
|
||||
<span class="rsp-alt-p3">
|
||||
<dl class="col-xs-5">
|
||||
<dt translate>Bay ID</dt>
|
||||
<dd><a ng-href="project/bays/{$ c.bay_uuid $}">{$ c.bay_uuid $}</a></dd>
|
||||
</dl>
|
||||
<dl class="col-xs-2">
|
||||
<dt translate>Memory</dt>
|
||||
<dd>{$ c.memorysize $} {$ c.memoryunit $}</dd>
|
||||
</dl>
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<dl class="col-xs-12">
|
||||
<dt translate>Command</dt>
|
||||
<dd>{$ c.command $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr hz-no-items items="table.containers"></tr>
|
||||
</tbody>
|
||||
<!--
|
||||
Table-footer:
|
||||
This is where we display number of items and pagination controls.
|
||||
-->
|
||||
<tfoot hz-table-footer items="table.containers"></tfoot>
|
||||
</table>
|
@ -38,13 +38,6 @@
|
||||
getBaymodels: getBaymodels,
|
||||
deleteBaymodel: deleteBaymodel,
|
||||
deleteBaymodels: deleteBaymodels,
|
||||
createContainer: createContainer,
|
||||
getContainer: getContainer,
|
||||
getContainers: getContainers,
|
||||
deleteContainer: deleteContainer,
|
||||
deleteContainers: deleteContainers,
|
||||
memoryUnits: memoryUnits,
|
||||
convertMemorySize: convertMemorySize,
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -130,76 +123,5 @@
|
||||
toastService.add('error', gettext('Unable to delete the Baymodels.'));
|
||||
})
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Containers //
|
||||
////////////////
|
||||
|
||||
function createContainer(params) {
|
||||
return apiService.post('/api/containers/containers/', params)
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to create Container.'));
|
||||
});
|
||||
}
|
||||
|
||||
function getContainer(id) {
|
||||
return apiService.get('/api/containers/containers/' + id)
|
||||
.success(function(data, status, headers, config) {
|
||||
convertMemorySize(data);
|
||||
return data;
|
||||
})
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to retrieve the Container.'));
|
||||
});
|
||||
}
|
||||
|
||||
function getContainers() {
|
||||
return apiService.get('/api/containers/containers/')
|
||||
.success(function(data, status, headers, config) {
|
||||
angular.forEach(data.items, function(container, idx){
|
||||
convertMemorySize(container);
|
||||
});
|
||||
return data;
|
||||
})
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to retrieve the Containers.'));
|
||||
});
|
||||
}
|
||||
|
||||
function deleteContainer(id, suppressError) {
|
||||
var promise = apiService.delete('/api/containers/containers/', [id]);
|
||||
return suppressError ? promise : promise.error(function() {
|
||||
var msg = gettext('Unable to delete the Container with id: %(id)s');
|
||||
toastService.add('error', interpolate(msg, { id: id }, true));
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME(shu-mutou): Unused for batch-delete in Horizon framework in Feb, 2016.
|
||||
function deleteContainers(ids) {
|
||||
return apiService.delete('/api/containers/containers/', ids)
|
||||
.error(function() {
|
||||
toastService.add('error', gettext('Unable to delete the Containers.'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var memoryUnits = { "b": gettext("bytes"),
|
||||
"k": gettext("KB"),
|
||||
"m": gettext("MB"),
|
||||
"g": gettext("GB")};
|
||||
|
||||
function convertMemorySize(container){
|
||||
container.memorysize = "";
|
||||
container.memoryunit = "";
|
||||
if(container.memory !== null && container.memory !== ""){
|
||||
// separate number and unit.
|
||||
var regex = /(\d+)([bkmg]?)/;
|
||||
var match = regex.exec(container.memory);
|
||||
container.memorysize = match[1];
|
||||
if(match[2]){
|
||||
container.memoryunit = memoryUnits[match[2]];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
|
@ -1,18 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Containers" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
<hz-page-header header="{$ 'Containers' | translate $}"/>
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block ng_route_base %}
|
||||
<base href="{{ WEBROOT }}"></base>
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div ng-view></div>
|
||||
{% endblock %}
|
@ -1,66 +0,0 @@
|
||||
# Copyright 2015 Cisco Systems, Inc.
|
||||
#
|
||||
# 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 magnum_ui import api
|
||||
from magnum_ui.test import helpers as test
|
||||
|
||||
|
||||
class MagnumApiTests(test.APITestCase):
|
||||
def test_container_list(self):
|
||||
containers = self.magnum_containers.list()
|
||||
form_data = {'marker': None,
|
||||
'limit': None,
|
||||
'sort_key': None,
|
||||
'sort_dir': None,
|
||||
'detail': False}
|
||||
|
||||
magnumclient = self.stub_magnumclient()
|
||||
magnumclient.containers = self.mox.CreateMockAnything()
|
||||
magnumclient.containers.list(**form_data).AndReturn(containers)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
api.magnum.container_list(self.request)
|
||||
|
||||
def test_container_get(self):
|
||||
container = self.magnum_containers.first()
|
||||
|
||||
magnumclient = self.stub_magnumclient()
|
||||
magnumclient.containers = self.mox.CreateMockAnything()
|
||||
magnumclient.containers.get(container['uuid']).AndReturn(container)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
api.magnum.container_show(self.request, container['uuid'])
|
||||
|
||||
def test_container_delete(self):
|
||||
container = self.magnum_containers.first()
|
||||
|
||||
magnumclient = self.stub_magnumclient()
|
||||
magnumclient.containers = self.mox.CreateMockAnything()
|
||||
magnumclient.containers.delete(container['uuid'])
|
||||
self.mox.ReplayAll()
|
||||
|
||||
api.magnum.container_delete(self.request, container['uuid'])
|
||||
|
||||
def test_container_create(self):
|
||||
container = self.magnum_containers.first()
|
||||
form_data = {'bay_uuid': container['bay'],
|
||||
'name': container['name']}
|
||||
|
||||
magnumclient = self.stub_magnumclient()
|
||||
magnumclient.containers = self.mox.CreateMockAnything()
|
||||
magnumclient.containers.create(**form_data)\
|
||||
.AndReturn(container)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
api.magnum.container_create(self.request, **form_data)
|
@ -103,46 +103,6 @@ class MagnumRestTestCase(test.TestCase):
|
||||
request,
|
||||
u'bay_id')
|
||||
|
||||
# Containers
|
||||
@mock.patch.object(magnum, 'magnum')
|
||||
def test_container_get(self, client):
|
||||
request = self.mock_rest_request()
|
||||
client.container_list.return_value = \
|
||||
mock_resource(TEST.magnum_containers.list())
|
||||
response = magnum.Containers().get(request)
|
||||
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertItemsCollectionEqual(response,
|
||||
TEST.magnum_containers.list())
|
||||
client.container_list.assert_called_once_with(request)
|
||||
|
||||
@mock.patch.object(magnum, 'magnum')
|
||||
def test_container_create(self, client):
|
||||
test_conts = mock_resource(TEST.magnum_containers.list())
|
||||
test_cont = test_conts[0]
|
||||
test_body = json.dumps(test_cont.to_dict())
|
||||
request = self.mock_rest_request(body=test_body)
|
||||
client.container_create.return_value = test_cont
|
||||
response = magnum.Containers().post(request)
|
||||
|
||||
self.assertStatusCode(response, 201)
|
||||
self.assertEqual(response['location'],
|
||||
'/api/containers/container/%s' % test_cont.uuid)
|
||||
client.container_create.assert_called_once_with(request,
|
||||
**test_cont.to_dict())
|
||||
|
||||
@mock.patch.object(magnum, 'magnum')
|
||||
def test_container_delete(self, client):
|
||||
test_container = TEST.magnum_containers.first()
|
||||
request = self.mock_rest_request(
|
||||
body='{"container_id":' + str(test_container['uuid']) + '}')
|
||||
response = magnum.Containers().delete(request)
|
||||
|
||||
self.assertStatusCode(response, 204)
|
||||
client.container_delete.assert_called_once_with(
|
||||
request,
|
||||
u'container_id')
|
||||
|
||||
|
||||
def mock_resource(resource):
|
||||
"""Utility function to make mocking more DRY"""
|
||||
|
@ -19,8 +19,6 @@ def data(TEST):
|
||||
# Test Data Containers
|
||||
TEST.baymodels = utils.TestDataContainer()
|
||||
TEST.bays = utils.TestDataContainer()
|
||||
# 'magnum_containers' to avoid Swift naming confusion
|
||||
TEST.magnum_containers = utils.TestDataContainer()
|
||||
|
||||
# Bay Models
|
||||
baymodel_dict_1 = {"uuid": 1,
|
||||
@ -53,13 +51,3 @@ def data(TEST):
|
||||
"timeout": 0}
|
||||
|
||||
TEST.bays.add(bay_dict_1)
|
||||
|
||||
# Containers
|
||||
container_dict_1 = {"uuid": 1,
|
||||
"name": "myapartmentsmellsofrichmahogany",
|
||||
"image": "",
|
||||
"bay": bay_dict_1["uuid"],
|
||||
"command": "",
|
||||
"memory": ""}
|
||||
|
||||
TEST.magnum_containers.add(container_dict_1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user