From 4738b11e078a6337c133a6c09bd1fbabdbd92046 Mon Sep 17 00:00:00 2001 From: shu-mutou Date: Fri, 16 Oct 2015 00:33:49 +0100 Subject: [PATCH] Add create action to bay panel Change-Id: I65100b9f2e52b35e727c077a7ed1c75900cd2b8b Partially Implements: blueprint bay-create Co-Authored-By: OTSUKA, Yuanying --- magnum_ui/api/magnum.py | 2 +- magnum_ui/api/rest/magnum.py | 4 +- .../dashboard/containers/bay/bay.module.js | 1 + .../containers/bay/create/bay-model.js | 72 +++++++++++++++ .../bay/create/create-workflow.service.js | 63 +++++++++++++ .../bay/create/info/bay.info.controller.js | 91 +++++++++++++++++++ .../containers/bay/create/info/info.help.html | 4 + .../containers/bay/create/info/info.html | 51 +++++++++++ .../bay/create/misc/bay.misc.controller.js | 43 +++++++++ .../containers/bay/create/misc/misc.help.html | 4 + .../containers/bay/create/misc/misc.html | 23 +++++ .../containers/bay/create/modal.controller.js | 71 +++++++++++++++ .../containers/bay/create/modal.spec.js | 0 .../bay/create/size/bay.size.controller.js | 43 +++++++++ .../containers/bay/create/size/size.help.html | 4 + .../containers/bay/create/size/size.html | 25 +++++ .../bay/create/wizard.controller.js | 45 +++++++++ .../dashboard/containers/bay/table/table.html | 22 +++-- .../dashboard/containers/magnum.service.js | 8 ++ magnum_ui/test/api_tests/rest_api_tests.py | 9 +- 20 files changed, 569 insertions(+), 16 deletions(-) create mode 100644 magnum_ui/static/dashboard/containers/bay/create/bay-model.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/create-workflow.service.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/info/bay.info.controller.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/info/info.help.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/info/info.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/misc/bay.misc.controller.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/misc/misc.help.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/misc/misc.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/modal.controller.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/modal.spec.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/size/bay.size.controller.js create mode 100644 magnum_ui/static/dashboard/containers/bay/create/size/size.help.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/size/size.html create mode 100644 magnum_ui/static/dashboard/containers/bay/create/wizard.controller.js diff --git a/magnum_ui/api/magnum.py b/magnum_ui/api/magnum.py index 0ef1379b..018b1298 100644 --- a/magnum_ui/api/magnum.py +++ b/magnum_ui/api/magnum.py @@ -85,7 +85,7 @@ def bay_create(request, **kwargs): else: raise exceptions.InvalidAttribute( "Key must be in %s" % ",".join(BAY_CREATE_ATTRS)) - return magnumclient(request).bays.create(args) + return magnumclient(request).bays.create(**args) def bay_update(request, id, patch): diff --git a/magnum_ui/api/rest/magnum.py b/magnum_ui/api/rest/magnum.py index 8b84109e..ba5f138c 100644 --- a/magnum_ui/api/rest/magnum.py +++ b/magnum_ui/api/rest/magnum.py @@ -100,8 +100,8 @@ class Bays(generic.View): """ new_bay = magnum.bay_create(request, **request.DATA) return rest_utils.CreatedResponse( - '/api/containers/bay/%s' % new_bay['uuid'], - new_bay) + '/api/containers/bay/%s' % new_bay.uuid, + new_bay.to_dict()) @urls.register diff --git a/magnum_ui/static/dashboard/containers/bay/bay.module.js b/magnum_ui/static/dashboard/containers/bay/bay.module.js index 962fa2e5..83f987ae 100644 --- a/magnum_ui/static/dashboard/containers/bay/bay.module.js +++ b/magnum_ui/static/dashboard/containers/bay/bay.module.js @@ -20,6 +20,7 @@ /** * @ngdoc overview * @name horizon.dashboard.containers.bay + * @ngModule * * @description * Provides all the services and widgets require to display the bay diff --git a/magnum_ui/static/dashboard/containers/bay/create/bay-model.js b/magnum_ui/static/dashboard/containers/bay/create/bay-model.js new file mode 100644 index 00000000..2be0f3f5 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/bay-model.js @@ -0,0 +1,72 @@ +/** + * 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.bay') + .factory('bayModel', bayModel); + + bayModel.$inject = [ + 'horizon.app.core.openstack-service-api.magnum' + ]; + + function bayModel(magnum) { + var model = { + newBaySpec: {}, + + // API methods + init: init, + createBay: createBay + }; + + function initNewBaySpec() { + model.newBaySpec = { + name: null, + baymodel_id: null, + master_count: null, + node_count: null, + discover_url: null, + bay_create_timeout: null + }; + } + + function init() { + // Reset the new Bay spec + initNewBaySpec(); + } + + function createBay() { + var finalSpec = angular.copy(model.newBaySpec); + + cleanNullProperties(finalSpec); + + return magnum.createBay(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) { + delete finalSpec[key]; + } + } + } + + return model; + } +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/create-workflow.service.js b/magnum_ui/static/dashboard/containers/bay/create/create-workflow.service.js new file mode 100644 index 00000000..e67d6a1e --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/create-workflow.service.js @@ -0,0 +1,63 @@ +/** + * 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.bay') + .factory('horizon.dashboard.containers.bay.workflow', bayWorkflow); + + bayWorkflow.$inject = [ + 'horizon.dashboard.containers.basePath', + 'horizon.app.core.workflow.factory' + ]; + + function bayWorkflow(basePath, dashboardWorkflow) { + return dashboardWorkflow({ + title: gettext('Create Bay'), + + steps: [ + { + title: gettext('Info'), + templateUrl: basePath + 'bay/create/info/info.html', + helpUrl: basePath + 'bay/create/info/info.help.html', + formName: 'bayInfoForm' + }, + { + title: gettext('Size'), + templateUrl: basePath + 'bay/create/size/size.html', + helpUrl: basePath + 'bay/create/size/size.help.html', + formName: 'baySizeForm' + }, + { + title: gettext('Misc'), + templateUrl: basePath + 'bay/create/misc/misc.html', + helpUrl: basePath + 'bay/create/misc/misc.help.html', + formName: 'bayMiscForm' + } + ], + + btnText: { + finish: gettext('Create') + }, + + btnIcon: { + finish: 'fa fa-cloud-download' + } + }); + } +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/info/bay.info.controller.js b/magnum_ui/static/dashboard/containers/bay/create/info/bay.info.controller.js new file mode 100644 index 00000000..ecd07084 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/info/bay.info.controller.js @@ -0,0 +1,91 @@ +/** + * 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 createBayInfoController + * @ngController + * + * @description + * Controller for the containers bay info step in create workflow + */ + angular + .module('horizon.dashboard.containers.bay') + .controller('createBayInfoController', createBayInfoController); + + createBayInfoController.$inject = [ + '$q', + '$scope', + 'horizon.dashboard.containers.basePath', + 'horizon.app.core.openstack-service-api.magnum' + ]; + + function createBayInfoController($q, $scope, basePath, magnum) { + var ctrl = this; + ctrl.baymodels = [{id:"", name: "Choose a Bay Model"}]; + $scope.model.newBaySpec.baymodel_id = ""; + $scope.baymodeldetail = { + name: "", + id: "", + coe: "", + image_id: "", + public: "", + registry_enabled: "", + tls_disabled: "", + apiserver_port: "" + }; + + $scope.changeBayModel = function(){ + // show Bay Model Detail + if(!$scope.model.newBaySpec.baymodel_id){ + $("#baymodel_detail").hide(); + $("#baymodel_detail_none").show(); + } else { + angular.forEach(ctrl.baymodels, function(model, idx){ + if($scope.model.newBaySpec.baymodel_id === model.id){ + $("#baymodel_detail").show(); + $("#baymodel_detail_none").hide(); + $scope.baymodeldetail.name = model.name; + $scope.baymodeldetail.id = model.id; + $scope.baymodeldetail.coe = model.coe; + $scope.baymodeldetail.image_id = model.image_id; + $scope.baymodeldetail.public = model.public; + $scope.baymodeldetail.registry_enabled = model.registry_enabled; + $scope.baymodeldetail.tls_disabled = model.tls_disabled; + $scope.baymodeldetail.apiserver_port = model.apiserver_port; + } + }); + } + }; + + init(); + $("#baymodel_detail").hide(); + $("#baymodel_detail_none").show(); + + function init() { + magnum.getBayModels({paginate: false}).success(onGetBayModels); + } + + function onGetBayModels(response) { + Array.prototype.push.apply(ctrl.baymodels, response.items); + } + + } + +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/info/info.help.html b/magnum_ui/static/dashboard/containers/bay/create/info/info.help.html new file mode 100644 index 00000000..25f9ea33 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/info/info.help.html @@ -0,0 +1,4 @@ +
+

Description:

+

Specify bay name and choose bay model.

+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/info/info.html b/magnum_ui/static/dashboard/containers/bay/create/info/info.html new file mode 100644 index 00000000..52452efd --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/info/info.html @@ -0,0 +1,51 @@ +
+

Bay Details

+ +
+
Please provide the name of the Bay.
+ +
+
+ + +
+
+ + +
+
+ +

Bay Model Detail

+
+ Choose a Bay Model +
+
+
+
Name
+
{$ baymodeldetail.name $}
+
ID
+
{$ baymodeldetail.id $}
+
COE
+
{$ baymodeldetail.coe $}
+
Image ID
+
{$ baymodeldetail.image_id $}
+
Public
+
{$ baymodeldetail.public $}
+
Registry Enabled
+
{$ baymodeldetail.registry_enabled $}
+
TLS Disabled
+
{$ baymodeldetail.tls_disabled $}
+
API Server Port
+
{$ baymodeldetail.apiserver_port $}
+
+
+ +
+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/misc/bay.misc.controller.js b/magnum_ui/static/dashboard/containers/bay/create/misc/bay.misc.controller.js new file mode 100644 index 00000000..d59610c9 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/misc/bay.misc.controller.js @@ -0,0 +1,43 @@ +/** + * 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 createBayMiscController + * @ngController + * + * @description + * Controller for the containers bay misc step in create workflow + */ + angular + .module('horizon.dashboard.containers.bay') + .controller('createBayMiscController', createBayMiscController); + + createBayMiscController.$inject = [ + '$scope', + 'horizon.dashboard.containers.basePath', + 'horizon.app.core.openstack-service-api.magnum' + ]; + + function createBayMiscController($scope, basePath, magnum) { + var ctrl = this; + + } + +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/misc/misc.help.html b/magnum_ui/static/dashboard/containers/bay/create/misc/misc.help.html new file mode 100644 index 00000000..a5d77193 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/misc/misc.help.html @@ -0,0 +1,4 @@ +
+

Description:

+

Specify conditions for bay creation.

+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/misc/misc.html b/magnum_ui/static/dashboard/containers/bay/create/misc/misc.html new file mode 100644 index 00000000..5061be22 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/misc/misc.html @@ -0,0 +1,23 @@ +
+

Miscellaneous

+ +
+
Please provide the miscellaneous for creation of the Bay.
+ +
+
+ + +
+
+ + +
+
+ +
+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/modal.controller.js b/magnum_ui/static/dashboard/containers/bay/create/modal.controller.js new file mode 100644 index 00000000..e03e377a --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/modal.controller.js @@ -0,0 +1,71 @@ +/** + * 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 containersBayModalController + * @ngController + * + * @description + * Controller for the containers bay create modal + */ + angular + .module('horizon.dashboard.containers.bay') + .controller('containersBayModalController', containersBayModalController); + + containersBayModalController.$inject = [ + '$modal', + '$window', + 'horizon.dashboard.containers.basePath', + 'horizon.app.core.openstack-service-api.magnum' + ]; + + function containersBayModalController($modal, $window, basePath, magnum) { + var ctrl = this; + + ctrl.openBayCreateWizard = openBayCreateWizard; + + function openBayCreateWizard(launchContext) { + var options = { + controller: 'ModalContainerController', + backdrop: 'static', + template: '"', + windowClass: 'modal-dialog-wizard', + resolve: { + launchContext: function() { + return launchContext; + } + } + }; + var launchInstanceModal = $modal.open(options); + var handleModalClose = function (redirectPropertyName) { + return function () { + if (launchContext && launchContext[redirectPropertyName]) { + $window.location.href = launchContext[redirectPropertyName]; + } + }; + }; + launchInstanceModal.result.then( + handleModalClose('successUrl'), + handleModalClose('dismissUrl') + ); + } + } + +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/modal.spec.js b/magnum_ui/static/dashboard/containers/bay/create/modal.spec.js new file mode 100644 index 00000000..e69de29b diff --git a/magnum_ui/static/dashboard/containers/bay/create/size/bay.size.controller.js b/magnum_ui/static/dashboard/containers/bay/create/size/bay.size.controller.js new file mode 100644 index 00000000..aae95993 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/size/bay.size.controller.js @@ -0,0 +1,43 @@ +/** + * 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 createBaySizeController + * @ngController + * + * @description + * Controller for the containers bay size step in create workflow + */ + angular + .module('horizon.dashboard.containers.bay') + .controller('createBaySizeController', createBaySizeController); + + createBaySizeController.$inject = [ + '$scope', + 'horizon.dashboard.containers.basePath', + 'horizon.app.core.openstack-service-api.magnum' + ]; + + function createBaySizeController($scope, basePath, magnum) { + var ctrl = this; + + } + +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/create/size/size.help.html b/magnum_ui/static/dashboard/containers/bay/create/size/size.help.html new file mode 100644 index 00000000..aaf29786 --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/size/size.help.html @@ -0,0 +1,4 @@ +
+

Description:

+

Specify the number of master nodes and bay nodes for the bay.

+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/size/size.html b/magnum_ui/static/dashboard/containers/bay/create/size/size.html new file mode 100644 index 00000000..701136ed --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/size/size.html @@ -0,0 +1,25 @@ +
+

Bay Size

+ +
+
Please provide the count of the master and node in this Bay.
+ +
+
+ + +
+
+ + +
+
+ +
+
diff --git a/magnum_ui/static/dashboard/containers/bay/create/wizard.controller.js b/magnum_ui/static/dashboard/containers/bay/create/wizard.controller.js new file mode 100644 index 00000000..38cbf84a --- /dev/null +++ b/magnum_ui/static/dashboard/containers/bay/create/wizard.controller.js @@ -0,0 +1,45 @@ +/** + * 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 createBayWizardController + * @ngController + * + * @description + * Controller for the containers bay create modal + */ + angular + .module('horizon.dashboard.containers.bay') + .controller('createBayWizardController', createBayWizardController); + + createBayWizardController.$inject = [ + '$scope', + 'bayModel', + 'horizon.dashboard.containers.bay.workflow' + ]; + + function createBayWizardController($scope, model, workflow) { + $scope.workflow = workflow; + $scope.model = model; + $scope.model.init(); + $scope.submit = $scope.model.createBay; + } + +})(); diff --git a/magnum_ui/static/dashboard/containers/bay/table/table.html b/magnum_ui/static/dashboard/containers/bay/table/table.html index c6add53a..bf97fc82 100644 --- a/magnum_ui/static/dashboard/containers/bay/table/table.html +++ b/magnum_ui/static/dashboard/containers/bay/table/table.html @@ -14,7 +14,14 @@ - + + + Create Bay + + Delete Bays - @@ -103,14 +109,12 @@ --> - - + Delete - - + + diff --git a/magnum_ui/static/dashboard/containers/magnum.service.js b/magnum_ui/static/dashboard/containers/magnum.service.js index 41f0bd57..083fa18a 100644 --- a/magnum_ui/static/dashboard/containers/magnum.service.js +++ b/magnum_ui/static/dashboard/containers/magnum.service.js @@ -27,6 +27,7 @@ function MagnumAPI(apiService, toastService) { var service = { + createBay: createBay, getBays: getBays, deleteBay: deleteBay, deleteBays: deleteBays, @@ -41,6 +42,13 @@ // Bays // ////////// + function createBay(params) { + return apiService.post('/api/containers/bays/', params) + .error(function() { + toastService.add('error', gettext('Unable to create Bay.')); + }); + } + function getBays() { return apiService.get('/api/containers/bays/') .error(function() { diff --git a/magnum_ui/test/api_tests/rest_api_tests.py b/magnum_ui/test/api_tests/rest_api_tests.py index aae678f6..fe55211d 100644 --- a/magnum_ui/test/api_tests/rest_api_tests.py +++ b/magnum_ui/test/api_tests/rest_api_tests.py @@ -77,17 +77,18 @@ class MagnumRestTestCase(test.TestCase): @mock.patch.object(magnum, 'magnum') def test_bay_create(self, client): - test_bay = TEST.bays.first() - test_body = json.dumps(test_bay) + test_bays = mock_resource(TEST.bays.list()) + test_bay = test_bays[0] + test_body = json.dumps(test_bay.to_dict()) request = self.mock_rest_request(body=test_body) client.bay_create.return_value = test_bay response = magnum.Bays().post(request) self.assertStatusCode(response, 201) self.assertEqual(response['location'], - '/api/containers/bay/%s' % test_bay['uuid']) + '/api/containers/bay/%s' % test_bay.uuid) client.bay_create.assert_called_once_with(request, - **test_bay) + **test_bay.to_dict()) @mock.patch.object(magnum, 'magnum') def test_bay_delete(self, client):