Change inputs for networks of cluster template into pulldowns
To be convinient to input netwok settings, this patch changes input forms for External Network, Fixed Network and Fixed Subnet in Cluster Template create/update dialogs to pulldowns. Change-Id: I7ba72ef432bd79e1eb074e9fdf29e2fcc8424377 Closes-Bug: #1570668
This commit is contained in:
parent
915227a9d7
commit
e1bcb3ceb7
@ -16,6 +16,7 @@ from django.views import generic
|
||||
|
||||
from magnum_ui.api import magnum
|
||||
|
||||
from openstack_dashboard.api import neutron
|
||||
from openstack_dashboard.api.rest import urls
|
||||
from openstack_dashboard.api.rest import utils as rest_utils
|
||||
|
||||
@ -181,3 +182,23 @@ class Certificates(generic.View):
|
||||
return rest_utils.CreatedResponse(
|
||||
'/api/container_infra/certificates/',
|
||||
new_cert.to_dict())
|
||||
|
||||
|
||||
@urls.register
|
||||
class Networks(generic.View):
|
||||
"""API for Neutron networks for Cluster Templates creation"""
|
||||
url_regex = r'container_infra/networks/$'
|
||||
|
||||
@rest_utils.ajax()
|
||||
def get(self, request):
|
||||
"""Get a list of the Networks for a project.
|
||||
|
||||
Networks includes external and private. Also, each network
|
||||
has subnets.
|
||||
The returned result is an object with property 'items' and each
|
||||
item under this is a Network.
|
||||
"""
|
||||
tenant_id = request.user.tenant_id
|
||||
result = neutron.network_list_for_tenant(request, tenant_id,
|
||||
include_external=True)
|
||||
return {'items': [n.to_dict() for n in result]}
|
||||
|
@ -117,6 +117,9 @@
|
||||
}
|
||||
}
|
||||
config.model.labels = labels; //
|
||||
|
||||
// update workflow
|
||||
workflow.update(config);
|
||||
}
|
||||
|
||||
return modal.open(config).then(submit);
|
||||
|
@ -41,6 +41,8 @@
|
||||
init: function (action, title) {
|
||||
action = title;
|
||||
return {model: model};
|
||||
},
|
||||
update: function () {
|
||||
}
|
||||
};
|
||||
|
||||
@ -66,6 +68,7 @@
|
||||
spyOn(magnum, 'getClusterTemplate').and.returnValue(deferred.promise);
|
||||
spyOn(magnum, 'updateClusterTemplate').and.returnValue(deferred.promise);
|
||||
spyOn(workflow, 'init').and.returnValue({model: model});
|
||||
spyOn(workflow, 'update').and.callThrough();
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
}));
|
||||
|
||||
|
@ -24,25 +24,27 @@
|
||||
ClusterTemplateWorkflow);
|
||||
|
||||
ClusterTemplateWorkflow.$inject = [
|
||||
'$q',
|
||||
'horizon.dashboard.container-infra.basePath',
|
||||
'horizon.app.core.workflow.factory',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.app.core.openstack-service-api.magnum',
|
||||
'horizon.app.core.openstack-service-api.nova',
|
||||
'horizon.app.core.openstack-service-api.glance'
|
||||
];
|
||||
|
||||
function ClusterTemplateWorkflow(basePath, workflowService, gettext, nova, glance) {
|
||||
function ClusterTemplateWorkflow($q, basePath, workflowService, gettext, magnum, nova, glance) {
|
||||
var workflow = {
|
||||
init: init
|
||||
init: init,
|
||||
update: update
|
||||
};
|
||||
|
||||
function init(action, title) {
|
||||
var schema, form, model;
|
||||
var images = [{value:"", name: gettext("Choose an Image")}];
|
||||
var nflavors = [{value:"", name: gettext("Choose a Flavor for the Node")}];
|
||||
var mflavors = [{value:"", name: gettext("Choose a Flavor for the Master Node")}];
|
||||
var keypairs = [{value:"", name: gettext("Choose a Keypair")}];
|
||||
var form, model, images, nflavors, mflavors, keypairs,
|
||||
externalNetworks, fixedNetworks, fixedSubnets;
|
||||
var fixedSubnetsInitial = gettext("Choose a Private Network at first");
|
||||
|
||||
function init(action, title) {
|
||||
var schema;
|
||||
var coes = [{value: '', name: gettext("Choose a Container Orchestration Engine")},
|
||||
{value: "swarm", name: gettext("Docker Swarm")},
|
||||
{value: "kubernetes", name: gettext("Kubernetes")},
|
||||
@ -161,30 +163,15 @@
|
||||
},
|
||||
'external_network_id': {
|
||||
title: gettext('External Network ID'),
|
||||
type: 'string',
|
||||
'x-schema-form': {
|
||||
type: 'string',
|
||||
placeholder: gettext(
|
||||
'The external Neutron network ID to connect to this cluster template')
|
||||
}
|
||||
type: 'string'
|
||||
},
|
||||
'fixed_network': {
|
||||
title: gettext('Fixed Network'),
|
||||
type: 'string',
|
||||
'x-schema-form': {
|
||||
type: 'string',
|
||||
placeholder: gettext(
|
||||
'The private Neutron network name to connect to this cluster template')
|
||||
}
|
||||
type: 'string'
|
||||
},
|
||||
'fixed_subnet': {
|
||||
title: gettext('Fixed Subnet'),
|
||||
type: 'string',
|
||||
'x-schema-form': {
|
||||
type: 'string',
|
||||
placeholder: gettext(
|
||||
'The private Neutron subnet name to connect to this cluster template')
|
||||
}
|
||||
type: 'string'
|
||||
},
|
||||
'dns_nameserver': {
|
||||
title: gettext('DNS'),
|
||||
@ -393,13 +380,22 @@
|
||||
},
|
||||
{
|
||||
key: 'external_network_id',
|
||||
type: 'select',
|
||||
titleMap: externalNetworks,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'fixed_network'
|
||||
key: 'fixed_network',
|
||||
type: 'select',
|
||||
titleMap: fixedNetworks,
|
||||
onChange: function () {
|
||||
changeFixedNetwork(model);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'fixed_subnet'
|
||||
key: 'fixed_subnet',
|
||||
type: 'select',
|
||||
titleMap: fixedSubnets
|
||||
},
|
||||
{
|
||||
key: 'dns_nameserver'
|
||||
@ -446,29 +442,6 @@
|
||||
}
|
||||
];
|
||||
|
||||
glance.getImages().then(onGetImages);
|
||||
nova.getFlavors(false, false).then(onGetFlavors);
|
||||
nova.getKeypairs().then(onGetKeypairs);
|
||||
|
||||
function onGetImages(response) {
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
images.push({value: item.name, name: item.name});
|
||||
});
|
||||
}
|
||||
|
||||
function onGetFlavors(response) {
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
nflavors.push({value: item.name, name: item.name});
|
||||
mflavors.push({value: item.name, name: item.name});
|
||||
});
|
||||
}
|
||||
|
||||
function onGetKeypairs(response) {
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
keypairs.push({value: item.keypair.name, name: item.keypair.name});
|
||||
});
|
||||
}
|
||||
|
||||
model = {
|
||||
name: "",
|
||||
coe: "",
|
||||
@ -502,10 +475,95 @@
|
||||
model: model
|
||||
};
|
||||
|
||||
update(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
// called by update.service
|
||||
function update(config) {
|
||||
$q.all({
|
||||
images: glance.getImages().then(onGetImages),
|
||||
flavors: nova.getFlavors(false, false).then(onGetFlavors),
|
||||
keypairs: nova.getKeypairs().then(onGetKeypairs),
|
||||
networks: magnum.getNetworks().then(onGetNetworks)
|
||||
}).then(function() {
|
||||
changeFixedNetwork(config.model, init);
|
||||
});
|
||||
}
|
||||
|
||||
function onGetImages(response) {
|
||||
images = [{value:"", name: gettext("Choose an Image")}];
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
images.push({value: item.name, name: item.name});
|
||||
});
|
||||
form[0].tabs[1].items[0].items[0].items[0].titleMap = images;
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(images);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onGetFlavors(response) {
|
||||
nflavors = [{value:"", name: gettext("Choose a Flavor for the Node")}];
|
||||
mflavors = [{value:"", name: gettext("Choose a Flavor for the Master Node")}];
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
nflavors.push({value: item.name, name: item.name});
|
||||
mflavors.push({value: item.name, name: item.name});
|
||||
});
|
||||
form[0].tabs[1].items[0].items[0].items[1].titleMap = nflavors;
|
||||
form[0].tabs[1].items[0].items[1].items[1].titleMap = mflavors;
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(nflavors);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onGetKeypairs(response) {
|
||||
keypairs = [{value:"", name: gettext("Choose a Keypair")}];
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
keypairs.push({value: item.keypair.name, name: item.keypair.name});
|
||||
});
|
||||
form[0].tabs[1].items[0].items[1].items[0].titleMap = keypairs;
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(keypairs);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onGetNetworks(response) {
|
||||
externalNetworks = [{value:"", name: gettext("Choose a External Network")}];
|
||||
fixedNetworks = [{value:"", name: gettext("Choose a Private Network")}];
|
||||
angular.forEach(response.data.items, function(item) {
|
||||
if (item["router:external"]) {
|
||||
externalNetworks.push({value: item.id, name: item.name});
|
||||
} else {
|
||||
fixedNetworks.push({value: item.id, name: item.name, subnets: item.subnets});
|
||||
}
|
||||
});
|
||||
form[0].tabs[2].items[0].items[0].items[4].titleMap = externalNetworks;
|
||||
form[0].tabs[2].items[0].items[0].items[5].titleMap = fixedNetworks;
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({
|
||||
externalNetworks: externalNetworks,
|
||||
fixedNetworks: fixedNetworks
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function changeFixedNetwork(model) {
|
||||
if (model.fixed_network) {
|
||||
fixedSubnets = [{value:"", name: gettext("Choose a Private Subnet")}];
|
||||
angular.forEach(fixedNetworks, function(fixed) {
|
||||
if (fixed.value === model.fixed_network) {
|
||||
angular.forEach(fixed.subnets, function(subnet) {
|
||||
fixedSubnets.push({value: subnet.id, name: subnet.name});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fixedSubnets = [{value:"", name: fixedSubnetsInitial}];
|
||||
model.fixed_subnet = "";
|
||||
}
|
||||
form[0].tabs[2].items[0].items[0].items[6].titleMap = fixedSubnets;
|
||||
}
|
||||
|
||||
return workflow;
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
describe('horizon.dashboard.container-infra.cluster-templates.workflow', function() {
|
||||
|
||||
var workflow, nova, glance, $q, deferred, keyDeferred;
|
||||
var workflow, magnum, nova, glance, $q, deferred, keyDeferred;
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.framework'));
|
||||
@ -31,6 +31,7 @@
|
||||
'horizon.dashboard.container-infra.cluster-templates.workflow');
|
||||
nova = $injector.get('horizon.app.core.openstack-service-api.nova');
|
||||
glance = $injector.get('horizon.app.core.openstack-service-api.glance');
|
||||
magnum = $injector.get('horizon.app.core.openstack-service-api.magnum');
|
||||
deferred = $q.defer();
|
||||
deferred.resolve({data:{items:{1:{name:1},2:{name:2}}}});
|
||||
keyDeferred = $q.defer();
|
||||
@ -38,7 +39,7 @@
|
||||
spyOn(glance, 'getImages').and.returnValue(deferred.promise);
|
||||
spyOn(nova, 'getFlavors').and.returnValue(deferred.promise);
|
||||
spyOn(nova, 'getKeypairs').and.returnValue(keyDeferred.promise);
|
||||
|
||||
spyOn(magnum, 'getNetworks').and.returnValue(deferred.promise);
|
||||
}));
|
||||
|
||||
it('should be init', inject(function($timeout) {
|
||||
|
@ -43,7 +43,8 @@
|
||||
deleteClusterTemplates: deleteClusterTemplates,
|
||||
showCertificate: showCertificate,
|
||||
signCertificate: signCertificate,
|
||||
downloadTextAsFile: downloadTextAsFile
|
||||
downloadTextAsFile: downloadTextAsFile,
|
||||
getNetworks: getNetworks
|
||||
};
|
||||
|
||||
return service;
|
||||
@ -180,5 +181,24 @@
|
||||
a.remove();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Networks //
|
||||
//////////////////
|
||||
|
||||
/**
|
||||
* @name getNetworks
|
||||
* @description
|
||||
* Get a list of networks for a tenant including external and private.
|
||||
* Also, each network has subnets.
|
||||
* @returns {Object} An object with property "items". Each item is a network.
|
||||
*/
|
||||
function getNetworks() {
|
||||
return apiService.get('/api/container_infra/networks/')
|
||||
.error(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the networks.'));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}());
|
||||
|
Loading…
x
Reference in New Issue
Block a user