diff --git a/zun_ui/api/client.py b/zun_ui/api/client.py index 7e17848..0499ed2 100644 --- a/zun_ui/api/client.py +++ b/zun_ui/api/client.py @@ -74,3 +74,15 @@ def container_list(request, limit=None, marker=None, sort_key=None, def container_show(request, id): return zunclient(request).containers.get(id) + + +def container_logs(request, id): + return zunclient(request).containers.logs(id) + + +def container_start(request, id): + return zunclient(request).containers.start(id) + + +def container_stop(request, id): + return zunclient(request).containers.stop(id) diff --git a/zun_ui/api/rest_api.py b/zun_ui/api/rest_api.py index 87fe047..78b88a9 100644 --- a/zun_ui/api/rest_api.py +++ b/zun_ui/api/rest_api.py @@ -39,6 +39,26 @@ class Container(generic.View): return change_to_id(client.container_show(request, id).to_dict()) +@urls.register +class ContainerActions(generic.View): + """API for retrieving a single container""" + url_regex = r'zun/containers/(?P[^/]+)/(?P[^/]+)$' + + @rest_utils.ajax() + def get(self, request, id, action): + """Get a specific container info""" + if action == 'logs': + return client.container_logs(request, id) + + @rest_utils.ajax() + def post(self, request, id, action): + """Execute a action of the Containers.""" + if action == 'start': + return client.container_start(request, id) + elif action == 'stop': + return client.container_stop(request, id) + + @urls.register class Containers(generic.View): """API for Zun Containers""" diff --git a/zun_ui/static/dashboard/container/containers/actions.module.js b/zun_ui/static/dashboard/container/containers/actions.module.js index 57f0bf2..8dbe078 100644 --- a/zun_ui/static/dashboard/container/containers/actions.module.js +++ b/zun_ui/static/dashboard/container/containers/actions.module.js @@ -30,6 +30,8 @@ 'horizon.framework.util.i18n.gettext', 'horizon.dashboard.container.containers.create.service', 'horizon.dashboard.container.containers.delete.service', + 'horizon.dashboard.container.containers.start.service', + 'horizon.dashboard.container.containers.stop.service', 'horizon.dashboard.container.containers.resourceType', ]; @@ -38,10 +40,26 @@ gettext, createContainerService, deleteContainerService, + startContainerService, + stopContainerService, resourceType) { var containersResourceType = registry.getResourceType(resourceType); containersResourceType.itemActions + .append({ + id: 'startContainerAction', + service: startContainerService, + template: { + text: gettext('Start Container') + } + }) + .append({ + id: 'stopContainerAction', + service: stopContainerService, + template: { + text: gettext('Stop Container') + } + }) .append({ id: 'deleteContainerAction', service: deleteContainerService, diff --git a/zun_ui/static/dashboard/container/containers/containers.scss b/zun_ui/static/dashboard/container/containers/containers.scss index e69de29..160d1aa 100644 --- a/zun_ui/static/dashboard/container/containers/containers.scss +++ b/zun_ui/static/dashboard/container/containers/containers.scss @@ -0,0 +1,3 @@ +.logs { + margin-top: 18px; +} \ No newline at end of file diff --git a/zun_ui/static/dashboard/container/containers/details/details.module.js b/zun_ui/static/dashboard/container/containers/details/details.module.js index 8060aa4..9b6a0b5 100644 --- a/zun_ui/static/dashboard/container/containers/details/details.module.js +++ b/zun_ui/static/dashboard/container/containers/details/details.module.js @@ -41,10 +41,16 @@ ) { registry.getResourceType(resourceType) .setLoadFunction(loadFunction) - .detailsViews.append({ + .detailsViews + .append({ id: 'containerDetailsOverview', name: gettext('Overview'), template: basePath + 'details/overview.html' + }) + .append({ + id: 'containerDetailsLogs', + name: gettext('Logs'), + template: basePath + 'details/logs.html' }); function loadFunction(identifier) { diff --git a/zun_ui/static/dashboard/container/containers/details/logs.controller.js b/zun_ui/static/dashboard/container/containers/details/logs.controller.js new file mode 100644 index 0000000..5840dc9 --- /dev/null +++ b/zun_ui/static/dashboard/container/containers/details/logs.controller.js @@ -0,0 +1,51 @@ +/* + * 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.container.containers') + .controller('horizon.dashboard.container.containers.LogsController', controller); + + controller.$inject = [ + '$scope', + 'horizon.app.core.openstack-service-api.zun', + 'horizon.dashboard.container.containers.resourceType', + 'horizon.dashboard.container.containers.events', + 'horizon.framework.conf.resource-type-registry.service' + ]; + + function controller( + $scope, + zun, + resourceType, + events, + registry + ) { + var ctrl = this; + ctrl.container = {}; + ctrl.logs = {}; + + $scope.context.loadPromise.then(onGetContainer); + + function onGetContainer(container) { + ctrl.container = container.data; + zun.logsContainer(ctrl.container.id).then(onGetLogs); + } + + function onGetLogs(logs) { + ctrl.logs = logs.data; + } + } +})(); diff --git a/zun_ui/static/dashboard/container/containers/details/logs.html b/zun_ui/static/dashboard/container/containers/details/logs.html new file mode 100644 index 0000000..0b5a418 --- /dev/null +++ b/zun_ui/static/dashboard/container/containers/details/logs.html @@ -0,0 +1,7 @@ +
+
+
+
{$ ctrl.logs $}
+
+
+
diff --git a/zun_ui/static/dashboard/container/containers/operations/start.service.js b/zun_ui/static/dashboard/container/containers/operations/start.service.js new file mode 100644 index 0000000..6e2f6da --- /dev/null +++ b/zun_ui/static/dashboard/container/containers/operations/start.service.js @@ -0,0 +1,68 @@ +/** + * 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.container.containers') + .factory('horizon.dashboard.container.containers.start.service', startService); + + startService.$inject = [ + 'horizon.framework.util.q.extensions', + 'horizon.framework.widgets.toast.service', + 'horizon.app.core.openstack-service-api.zun' + ]; + + /** + * @ngDoc factory + * @name horizon.dashboard.container.containers.start.service + * @Description + * Start container. + */ + function startService( + $qExtensions, toast, zun + ) { + + var message = { + success: gettext('Container %s was successfully started.') + }; + + 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() { + } + + function allowed() { + return $qExtensions.booleanAsPromise(true); + } + + function perform(selected) { + // start selected container + return zun.startContainer(selected.id).success(function(response) { + toast.add('success', interpolate(message.success, [selected.name])); + }); + } + } +})(); diff --git a/zun_ui/static/dashboard/container/containers/operations/stop.service.js b/zun_ui/static/dashboard/container/containers/operations/stop.service.js new file mode 100644 index 0000000..11683b0 --- /dev/null +++ b/zun_ui/static/dashboard/container/containers/operations/stop.service.js @@ -0,0 +1,68 @@ +/** + * 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.container.containers') + .factory('horizon.dashboard.container.containers.stop.service', stopService); + + stopService.$inject = [ + 'horizon.framework.util.q.extensions', + 'horizon.framework.widgets.toast.service', + 'horizon.app.core.openstack-service-api.zun' + ]; + + /** + * @ngDoc factory + * @name horizon.dashboard.container.containers.stop.service + * @Description + * Stop container. + */ + function stopService( + $qExtensions, toast, zun + ) { + + var message = { + success: gettext('Container %s was successfully stoped.') + }; + + 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() { + } + + function allowed() { + return $qExtensions.booleanAsPromise(true); + } + + function perform(selected) { + // start selected container + return zun.stopContainer(selected.id).success(function(response) { + toast.add('success', interpolate(message.success, [selected.name])); + }); + } + } +})(); diff --git a/zun_ui/static/dashboard/container/zun.service.js b/zun_ui/static/dashboard/container/zun.service.js index 1be1046..1034d38 100644 --- a/zun_ui/static/dashboard/container/zun.service.js +++ b/zun_ui/static/dashboard/container/zun.service.js @@ -31,6 +31,9 @@ getContainers: getContainers, deleteContainer: deleteContainer, deleteContainers: deleteContainers, + startContainer: startContainer, + stopContainer: stopContainer, + logsContainer: logsContainer, }; return service; @@ -73,7 +76,29 @@ return apiService.delete('/api/zun/containers/', ids) .error(function() { toastService.add('error', gettext('Unable to delete the Containers.')); - }) + }); } + + function startContainer(id) { + return apiService.post('/api/zun/containers/' + id + '/start') + .error(function() { + toastService.add('error', gettext('Unable to start Container')); + }); + } + + function stopContainer(id) { + return apiService.post('/api/zun/containers/' + id + '/stop') + .error(function() { + toastService.add('error', gettext('Unable to stop Container')); + }); + } + + function logsContainer(id) { + return apiService.get('/api/zun/containers/' + id + '/logs') + .error(function() { + toastService.add('error', gettext('Unable to get logs of Container')); + }); + } + } }());