Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#6758] Platform: Reuse on-premise instance once the instance got delete. #6970

Merged
merged 12 commits into from
Feb 16, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import com.yugabyte.yw.common.services.YBClientService;
import com.yugabyte.yw.forms.UniverseTaskParams.EncryptionAtRestConfig.OpType;
import com.yugabyte.yw.forms.UniverseDefinitionTaskParams.Cluster;
import com.yugabyte.yw.models.Universe.UniverseUpdater;
import com.yugabyte.yw.models.helpers.NodeDetails;
import com.yugabyte.yw.models.helpers.TableDetails;
Expand Down Expand Up @@ -312,10 +313,20 @@ public SubTaskGroup createDestroyServerTasks(Collection<NodeDetails> nodes,
SubTaskGroup subTaskGroup = new SubTaskGroup("AnsibleDestroyServers", executor);
for (NodeDetails node : nodes) {
// Check if the private ip for the node is set. If not, that means we don't have
// a clean state to delete the node. Log it and skip the node.
if (node.cloudInfo.private_ip == null) {
// a clean state to delete the node. Log it, free up the onprem node
// so that the client can use the node instance to create another universe.
if (node.cloudInfo.private_ip == null){
LOG.warn(String.format("Node %s doesn't have a private IP. Skipping node delete.",
node.nodeName));
if (node.cloudInfo.cloud.equals(
com.yugabyte.yw.commissioner.Common.CloudType.onprem.name())) {
try {
NodeInstance providerNode = NodeInstance.getByName(node.nodeName);
providerNode.clearNodeDetails();
} catch (Exception ex) {
LOG.warn("On-prem node {} doesn't have a linked instance ", node.nodeName);
}
}
continue;
}
AnsibleDestroyServer.Params params = new AnsibleDestroyServer.Params();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) YugaByte, Inc.

package com.yugabyte.yw.commissioner.tasks;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.yugabyte.yw.commissioner.SubTaskGroupQueue;
import com.yugabyte.yw.commissioner.Common.CloudType;
import com.yugabyte.yw.common.FakeDBApplication;
import com.yugabyte.yw.forms.NodeInstanceFormData.NodeInstanceData;
import com.yugabyte.yw.forms.UniverseTaskParams;
import com.yugabyte.yw.models.NodeInstance;
import com.yugabyte.yw.models.helpers.CloudSpecificInfo;
import com.yugabyte.yw.models.helpers.NodeDetails;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import junitparams.converters.Nullable;

@RunWith(JUnitParamsRunner.class)
public class UniverseTaskBaseTest extends FakeDBApplication {

private static final int NUM_NODES = 3;
private TestUniverseTaskBase universeTaskBase = new TestUniverseTaskBase();

private List<NodeDetails> setupNodeDetails(CloudType cloudType, String privateIp) {
List<NodeDetails> nodes = new ArrayList<>();
for (int i = 0; i < NUM_NODES; i++) {
NodeDetails node = new NodeDetails();
node.nodeUuid = UUID.randomUUID();
node.azUuid = UUID.randomUUID();
node.nodeName = "node_" + String.valueOf(i);
node.cloudInfo = new CloudSpecificInfo();
node.cloudInfo.cloud = cloudType.name();
node.cloudInfo.private_ip = privateIp;

NodeInstance nodeInstance = new NodeInstance();
NodeInstanceData details = new NodeInstanceData();
details.instanceName = node.nodeName + "_instance";
details.ip = "ip";
details.nodeName = node.nodeName;
details.instanceType = "type";
details.zone = "zone";
nodeInstance.setDetails(details);
nodeInstance.setNodeName(node.nodeName);
nodeInstance.nodeUuid = node.nodeUuid;
nodeInstance.instanceName = details.instanceName;
nodeInstance.zoneUuid = node.azUuid;
nodeInstance.inUse = true;
nodeInstance.instanceTypeCode = details.instanceType;

nodeInstance.save();
nodes.add(node);
}
return nodes;
}

@Test
// @formatter:off
@Parameters({
"aws, 1.1.1.1, false", // aws with private IP
"aws, null, false", // aws without private IP
"onprem, 1.1.1.1, false", // onprem with private IP
"onprem, null, true" // onprem without private IP
})
// @formatter:on
public void testCreateDestroyServerTasks(
CloudType cloudType, @Nullable String privateIp,boolean detailsCleanExpected) {

List<NodeDetails> nodes = setupNodeDetails(cloudType, privateIp);
universeTaskBase.createDestroyServerTasks(nodes, false, false);
for (int i = 0; i < NUM_NODES; i++) {
// Node should not be in use.
NodeInstance ni = NodeInstance.get(nodes.get(i).nodeUuid);
assertEquals(detailsCleanExpected, !ni.inUse);
// If the instance details are cleared then it is not possible to find it by node name
try {
NodeInstance nodeInstance = NodeInstance.getByName(nodes.get(i).nodeName);
assertFalse(detailsCleanExpected);
assertTrue(nodeInstance.inUse);
} catch (Exception e) {
assertTrue(detailsCleanExpected);
}
}
}

private static class TestUniverseTaskBase extends UniverseTaskBase {

public TestUniverseTaskBase() {
super();
subTaskGroupQueue = new SubTaskGroupQueue(UUID.randomUUID());
taskParams = new UniverseTaskParams();
}

@Override
public void run() {}
}
}