Skip to content

Commit

Permalink
fix delete vr additional public network error
Browse files Browse the repository at this point in the history
deltion additional public network will not delete virtual router.
but delete the nic of the addition public network

Fix ZSTAC-10692
  • Loading branch information
ruansteve committed Mar 31, 2018
1 parent d1da4b4 commit 6506e76
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.zstack.core.CoreGlobalProperty;
import org.zstack.core.Platform;
import org.zstack.core.ansible.AnsibleFacade;
import org.zstack.core.asyncbatch.While;
import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.cloudbus.CloudBusCallBack;
import org.zstack.core.cloudbus.MessageSafe;
Expand All @@ -25,11 +26,14 @@
import org.zstack.header.configuration.InstanceOfferingInventory;
import org.zstack.header.configuration.InstanceOfferingState;
import org.zstack.header.configuration.InstanceOfferingVO;
import org.zstack.header.core.FutureCompletion;
import org.zstack.header.core.NoErrorCompletion;
import org.zstack.header.core.ReturnValueCompletion;
import org.zstack.header.core.workflow.Flow;
import org.zstack.header.core.workflow.FlowChain;
import org.zstack.header.core.workflow.WhileCompletion;
import org.zstack.header.errorcode.ErrorCode;
import org.zstack.header.errorcode.ErrorCodeList;
import org.zstack.header.errorcode.OperationFailureException;
import org.zstack.header.exception.CloudRuntimeException;
import org.zstack.header.host.HypervisorType;
Expand Down Expand Up @@ -1418,6 +1422,63 @@ protected List<VmNicInventory> scripts() {
}.execute();
}

private void applianceVmsCascadeDeleteAdditionPubclicNic(List<VmNicInventory> toDeleteNics) {
ErrorCodeList errList = new ErrorCodeList();
FutureCompletion completion = new FutureCompletion(null);
new While<>(toDeleteNics).each((VmNicInventory nic, WhileCompletion completion1) -> {
if (!dbf.isExist(nic.getUuid(), VmNicVO.class)) {
logger.debug(String.format("nic[uuid:%s] not exists, skip", nic.getUuid()));
completion1.done();
return;
}
DetachNicFromVmMsg msg = new DetachNicFromVmMsg();
msg.setVmNicUuid(nic.getUuid());
msg.setVmInstanceUuid(nic.getVmInstanceUuid());
bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, nic.getVmInstanceUuid());
bus.send(msg, new CloudBusCallBack(null) {
@Override
public void run(MessageReply reply) {
if (!reply.isSuccess()) {
if (!dbf.isExist(nic.getUuid(), VmNicVO.class)) {
logger.info(String.format("nic[uuid:%s] not exists, mark it as success", nic.getUuid()));
completion1.done();
} else {
errList.getCauses().add(reply.getError());
logger.error(String.format("detach nic[uuid: %s] for " +
"delete l3[uuid: %s] failed", nic.getUuid(), nic.getL3NetworkUuid()));
completion1.allDone();
}
} else {
logger.debug(String.format("detach nic[uuid: %s] for " +
"delete l3[uuid: %s] success", nic.getUuid(), nic.getL3NetworkUuid()));
completion1.done();
}
}
});
}).run(new NoErrorCompletion() {
@Override
public void done() {
if (!errList.getCauses().isEmpty()) {
completion.fail(errList.getCauses().get(0));
} else {
logger.info(String.format("detach nics[%s] for delete l3[uuid:%s] success",
toDeleteNics.stream()
.map(n -> n.getUuid())
.collect(Collectors.toList()),
toDeleteNics.stream().map(n-> n.getL3NetworkUuid()).collect(Collectors.toSet())));
completion.success();
}
}
});

completion.await(TimeUnit.MINUTES.toMillis(30));
if (!completion.isSuccess()) {
throw new OperationFailureException(operr("can not detach nic [uuid:%s]", toDeleteNics.stream()
.map(n -> n.getUuid())
.collect(Collectors.toList())).causedBy(completion.getErrorCode()));
}
}

private List<ApplianceVmVO> applianceVmsToBeDeleted(List<ApplianceVmVO> applianceVmVOS, List<String> deletedUuids) {
List<ApplianceVmVO> vos = new ArrayList<>();
for (ApplianceVmVO vo : applianceVmVOS) {
Expand All @@ -1434,22 +1495,49 @@ private List<ApplianceVmVO> applianceVmsToBeDeleted(List<ApplianceVmVO> applianc
}
}
}

return vos;
}

List<VmNicInventory> applianceVmsAdditionalPublicNic(List<ApplianceVmVO> applianceVmVOS, List<String> parentIssuerUuids) {
List<VmNicInventory> toDeleteNics = new ArrayList<>();
for (ApplianceVmVO vo : applianceVmVOS) {
VirtualRouterVmInventory vrInv = VirtualRouterVmInventory.valueOf(dbf.findByUuid(vo.getUuid(), VirtualRouterVmVO.class));
for (VmNicInventory nic : vrInv.getAdditionalPublicNics()) {
if (parentIssuerUuids.contains(nic.getL3NetworkUuid())) {
toDeleteNics.add(nic);
}
}
}

return toDeleteNics;
}

@Override
public List<ApplianceVmVO> filterApplianceVmCascade(List<ApplianceVmVO> applianceVmVOS, String parentIssuer, List<String> parentIssuerUuids) {

if (parentIssuer.equals(L3NetworkVO.class.getSimpleName())) {
return applianceVmsToBeDeleted(applianceVmVOS, parentIssuerUuids);
List<ApplianceVmVO> vos = applianceVmsToBeDeleted(applianceVmVOS, parentIssuerUuids);

applianceVmVOS.removeAll(vos);
List<VmNicInventory> toDeleteNics = applianceVmsAdditionalPublicNic(applianceVmVOS, parentIssuerUuids);
applianceVmsCascadeDeleteAdditionPubclicNic(toDeleteNics);

return vos;
} else if (parentIssuer.equals(IpRangeVO.class.getSimpleName())) {
final List<String> iprL3Uuids = CollectionUtils.transformToList((List<String>) parentIssuerUuids, new Function<String, String>() {
@Override
public String call(String arg) {
return Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, arg).select(IpRangeVO_.l3NetworkUuid).findValue();
}
});
return applianceVmsToBeDeleted(applianceVmVOS, iprL3Uuids);
List<ApplianceVmVO> vos = applianceVmsToBeDeleted(applianceVmVOS, iprL3Uuids);

applianceVmVOS.removeAll(vos);
List<VmNicInventory> toDeleteNics = applianceVmsAdditionalPublicNic(applianceVmVOS, iprL3Uuids);
applianceVmsCascadeDeleteAdditionPubclicNic(toDeleteNics);

return vos;
} else {
return applianceVmVOS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ public static boolean isPublicNic(VmNicInventory nic) {
return (mask & PUBLIC_NIC_MASK) != 0;
}

public static boolean isAddinitionalPublicNic(VmNicInventory nic) {
String meta = nic.getMetaData();
if (meta == null) {
return false;
}

int mask = Integer.valueOf(meta);
return (mask & ADDITIONAL_PUBLIC_NIC_MASK) != 0;
}

public static boolean isManagementNic(VmNicInventory nic) {
String meta = nic.getMetaData();
if (meta == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ public List<VmNicInventory> getGuestNics() {
return guestNics;
}

public List<VmNicInventory> getAdditionalPublicNics() {
if (getVmNics() == null) {
return null;
}
List<VmNicInventory> nics = new ArrayList<>();

for (VmNicInventory n : getVmNics()) {
if (VirtualRouterNicMetaData.isAddinitionalPublicNic(n)) {
nics.add(n);
}
}

return nics;
}

public VmNicInventory getGuestNicByL3NetworkUuid(String l3uuid) {
for (VmNicInventory nic : getVmNics()) {
if (l3uuid.equals(nic.getL3NetworkUuid())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,33 @@ class VirtualRouterDeletePublicNetworkCase extends SubCase {
delegate.netmask = "255.255.255.0"
}

L3NetworkInventory l3_2 = createL3Network {
delegate.category = "Public"
delegate.l2NetworkUuid = l2.uuid
delegate.name = "pubL3-3"
}

addIpRange {
delegate.name = "TestIpRange-2"
delegate.l3NetworkUuid = l3_2.uuid
delegate.startIp = "11.168.210.10"
delegate.endIp = "11.168.210.253"
delegate.gateway = "11.168.210.1"
delegate.netmask = "255.255.255.0"
}

VirtualRouterVmVO vr = Q.New(VirtualRouterVmVO.class).find()

VmInstanceInventory inv = attachL3NetworkToVm {
attachL3NetworkToVm {
delegate.l3NetworkUuid = l3_1.getUuid()
delegate.vmInstanceUuid = vr.uuid
}

attachL3NetworkToVm {
delegate.l3NetworkUuid = l3_2.getUuid()
delegate.vmInstanceUuid = vr.uuid
}

deleteL3Network {
uuid = l3_1.uuid
}
Expand All @@ -71,8 +91,9 @@ class VirtualRouterDeletePublicNetworkCase extends SubCase {
assert vr != null
assert vr.getPublicNetworkUuid() == pub.uuid
assert vr.getManagementNetworkUuid() == pub.uuid
assert vr.getVmNics().size() == 3
for (VmNicVO nic : vr.getVmNics()) {
assert nic.l3NetworkUuid != l3_1.uuid
assert nic.l3NetworkUuid != l3_1.uuid && nic.l3NetworkUuid != null
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,36 @@ class VirtualRouterDeletePublicNetworkIpRangeCase extends SubCase {
delegate.netmask = "255.255.255.0"
}

L3NetworkInventory l3_2 = createL3Network {
delegate.category = "Public"
delegate.l2NetworkUuid = l2.uuid
delegate.name = "pubL3-3"
}

addIpRange {
delegate.name = "TestIpRange-2"
delegate.l3NetworkUuid = l3_2.uuid
delegate.startIp = "11.168.210.10"
delegate.endIp = "11.168.210.253"
delegate.gateway = "11.168.210.1"
delegate.netmask = "255.255.255.0"
}

VirtualRouterVmVO vr = Q.New(VirtualRouterVmVO.class).find()
assert vr != null
assert vr.getPublicNetworkUuid() == pub.uuid
assert vr.getManagementNetworkUuid() == pub.uuid

VmInstanceInventory inv = attachL3NetworkToVm {
attachL3NetworkToVm {
delegate.l3NetworkUuid = l3_1.getUuid()
delegate.vmInstanceUuid = vr.uuid
}

attachL3NetworkToVm {
delegate.l3NetworkUuid = l3_2.getUuid()
delegate.vmInstanceUuid = vr.uuid
}

deleteIpRange {
uuid = iprInv.uuid
}
Expand All @@ -74,6 +94,10 @@ class VirtualRouterDeletePublicNetworkIpRangeCase extends SubCase {
assert vr != null
assert vr.getPublicNetworkUuid() == pub.uuid
assert vr.getManagementNetworkUuid() == pub.uuid
assert vr.getVmNics().size() == 3
for (VmNicVO nic : vr.getVmNics()) {
assert nic.l3NetworkUuid != l3_1.uuid && nic.l3NetworkUuid != null
}
}

@Override
Expand Down

0 comments on commit 6506e76

Please sign in to comment.