Fix resize for CAPI clusters
Clusters created by the magnum-capi-helm driver do not have a heat stack, so resize currently fails as it depends on the heat stack for a list of worker nodes. To fix this, we change to querying the nodegroup information and use that instead. We keep the old heat stack way for now, as that is the way to get a list of worker nodes to select candidate(s) for scaling down. This is not available in capi driver yet, so capi will return an empty list of worker nodes. Change-Id: I0d66fc02a7f2c608a4a0b09b98c343017e04ed41
This commit is contained in:
parent
c9fdb537ea
commit
a5ff9ecb4f
@ -289,3 +289,8 @@ def quotas_update(request, project_id, resource, **kwargs):
|
||||
|
||||
def quotas_delete(request, project_id, resource):
|
||||
return magnumclient(request).quotas.delete(project_id, resource)
|
||||
|
||||
|
||||
def nodegroup_list(request, cluster_id=None, limit=None, marker=None):
|
||||
return magnumclient(request).nodegroups.list(cluster_id, limit=limit,
|
||||
marker=marker)
|
||||
|
@ -25,6 +25,7 @@ from django.views import generic
|
||||
from magnum_ui.api import heat
|
||||
from magnum_ui.api import magnum
|
||||
|
||||
from heatclient import exc as heatexc
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.api import neutron
|
||||
from openstack_dashboard.api.rest import urls
|
||||
@ -237,18 +238,29 @@ class ClusterResize(generic.View):
|
||||
print(e)
|
||||
return HttpResponseNotFound()
|
||||
|
||||
stack = heat.stack_get(request, cluster["stack_id"])
|
||||
search_opts = {"name": "%s-" % stack.stack_name}
|
||||
servers = api.nova.server_list(request, search_opts=search_opts)[0]
|
||||
try:
|
||||
ngs = magnum.nodegroup_list(request, cluster_id)
|
||||
nodegroups = [n.to_dict() for n in ngs]
|
||||
except AttributeError:
|
||||
return HttpResponseNotFound()
|
||||
|
||||
try:
|
||||
stack = heat.stack_get(request, cluster["stack_id"])
|
||||
except heatexc.HTTPNotFound:
|
||||
stack = None
|
||||
worker_nodes = []
|
||||
for server in servers:
|
||||
if (server.name.startswith("%s-minion" % stack.stack_name) or
|
||||
server.name.startswith("%s-node" % stack.stack_name)):
|
||||
worker_nodes.append({"name": server.name, "id": server.id})
|
||||
if stack:
|
||||
search_opts = {"name": "%s-" % stack.stack_name}
|
||||
servers = api.nova.server_list(request, search_opts=search_opts)[0]
|
||||
|
||||
for server in servers:
|
||||
if (server.name.startswith("%s-minion" % stack.stack_name) or
|
||||
server.name.startswith("%s-node" % stack.stack_name)):
|
||||
worker_nodes.append({"name": server.name, "id": server.id})
|
||||
|
||||
return {"cluster": change_to_id(cluster),
|
||||
"worker_nodes": worker_nodes}
|
||||
"worker_nodes": worker_nodes,
|
||||
"nodegroups": nodegroups}
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
def post(self, request, cluster_id):
|
||||
|
@ -70,7 +70,7 @@
|
||||
formModel = getFormModelDefaults();
|
||||
formModel.id = selected.id;
|
||||
|
||||
modalConfig = constructModalConfig(response.data.worker_nodes);
|
||||
modalConfig = constructModalConfig(response.data.nodegroups, response.data.worker_nodes);
|
||||
|
||||
deferred.resolve(modal.open(modalConfig).then(onModalSubmit));
|
||||
$scope.model = formModel;
|
||||
@ -91,9 +91,13 @@
|
||||
return $qExtensions.booleanAsPromise(true);
|
||||
}
|
||||
|
||||
function constructModalConfig(workerNodesList) {
|
||||
formModel.original_node_count = workerNodesList.length;
|
||||
formModel.node_count = workerNodesList.length;
|
||||
function constructModalConfig(nodegroups, workerNodesList) {
|
||||
var defaultWorker = nodegroups.filter(function(ng) {
|
||||
return ng.name === 'default-worker';
|
||||
})[0];
|
||||
formModel.original_node_count = defaultWorker.node_count;
|
||||
formModel.node_count = defaultWorker.node_count;
|
||||
formModel.worker_nodes = workerNodesList;
|
||||
|
||||
return {
|
||||
title: gettext('Resize Cluster'),
|
||||
@ -116,8 +120,8 @@
|
||||
form: [
|
||||
{
|
||||
key: 'node_count',
|
||||
title: gettext('Node Count'),
|
||||
placeholder: gettext('The cluster node count.'),
|
||||
title: gettext('Node Count (default-worker)'),
|
||||
placeholder: gettext('The default-worker nodegroup node_count.'),
|
||||
required: true,
|
||||
validationMessage: {
|
||||
101: gettext('You cannot resize to fewer than zero worker nodes.')
|
||||
@ -129,7 +133,8 @@
|
||||
type: 'checkboxes',
|
||||
title: gettext('Choose nodes to remove (Optional)'),
|
||||
titleMap: generateNodesTitleMap(workerNodesList),
|
||||
condition: 'model.node_count < model.original_node_count',
|
||||
condition: 'model.node_count < model.original_node_count && ' +
|
||||
'model.worker_nodes.length > 0',
|
||||
onChange: validateNodeRemovalCount,
|
||||
validationMessage: {
|
||||
nodeRemovalCountExceeded: gettext('You may only select as many nodes ' +
|
||||
|
@ -67,10 +67,23 @@
|
||||
|
||||
it('should open the modal, hide the loading spinner and check the form model',
|
||||
inject(function($timeout) {
|
||||
var mockWorkerNodes = [{id: "456", name: "Worker Node 1"}];
|
||||
// 2 nodegroups, default-worker and another-nodegroup, with 2 and 3
|
||||
// nodes respectively. cluster.node_count will be total nodes in all
|
||||
// nodegroups
|
||||
var mockDefaultWorker = {name: 'default-worker', node_count: 2};
|
||||
var mockNodegroups = [mockDefaultWorker,
|
||||
{name: 'default-master', node_count: 1},
|
||||
{name: 'another-nodegroup', node_count: 3}];
|
||||
var mockCluster = {node_count: 5};
|
||||
|
||||
// only populated with heat, [] for capi
|
||||
var mockWorkerNodes = [{id: "456", name: "Worker Node 1"},
|
||||
{id: "457", name: "Worker Node 2"}];
|
||||
|
||||
deferred = $q.defer();
|
||||
deferred.resolve({data: {cluster: {}, worker_nodes: mockWorkerNodes}});
|
||||
deferred.resolve({data: {cluster: mockCluster,
|
||||
worker_nodes: mockWorkerNodes,
|
||||
nodegroups: mockNodegroups}});
|
||||
spyOn(magnum, 'getClusterNodes').and.returnValue(deferred.promise);
|
||||
|
||||
service.perform(selected, $scope);
|
||||
@ -82,8 +95,8 @@
|
||||
|
||||
// Check if the form's model skeleton is correct
|
||||
expect(modalConfig.model.id).toBe(selected.id);
|
||||
expect(modalConfig.model.original_node_count).toBe(mockWorkerNodes.length);
|
||||
expect(modalConfig.model.node_count).toBe(mockWorkerNodes.length);
|
||||
expect(modalConfig.model.original_node_count).toBe(mockDefaultWorker.node_count);
|
||||
expect(modalConfig.model.node_count).toBe(mockDefaultWorker.node_count);
|
||||
expect(modalConfig.title).toBeDefined();
|
||||
expect(modalConfig.schema).toBeDefined();
|
||||
expect(modalConfig.form).toBeDefined();
|
||||
|
Loading…
x
Reference in New Issue
Block a user