diff --git a/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java index e9ffde6e721..b999b06387e 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java @@ -32,7 +32,7 @@ public class AttachedVolumePrimaryStorageAllocatorFlow extends AbstractHostAlloc public void allocate() { throwExceptionIfIAmTheFirstFlow(); - if (VmOperation.NewCreate.toString().equals(spec.getVmOperation())) { + if (VmOperation.NewCreate.toString().equals(spec.getVmOperation()) || VmOperation.MigrateStorage.toString().equals(spec.getVmOperation())) { next(candidates); return; } diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java index c229cde82ad..35b5c713362 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java @@ -142,11 +142,11 @@ private List filterHostHavingAccessiblePrimaryStorage(List huuid private List allocateFromCandidates() { List huuids = getHostUuidsFromCandidates(); Set requiredPsUuids = spec.getRequiredPrimaryStorageUuids(); - if (!VmOperation.NewCreate.toString().equals(spec.getVmOperation())) { - return filterHostHavingAccessiblePrimaryStorage(huuids, spec); - } else { + if (VmOperation.NewCreate.toString().equals(spec.getVmOperation()) || VmOperation.MigrateStorage.toString().equals(spec.getVmOperation())) { huuids = filterHostHavingAccessiblePrimaryStorage(huuids, spec) .stream().map(ResourceVO::getUuid).collect(Collectors.toList()); + } else { + return filterHostHavingAccessiblePrimaryStorage(huuids, spec); } if (huuids.isEmpty()) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java index 0d046d2cc7e..c98bb3403bf 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java @@ -40,7 +40,7 @@ public class TagAllocatorFlow extends AbstractHostAllocatorFlow { private List instanceOfferingExtensions; private List diskOfferingExtensions; - public TagAllocatorFlow() { + private void loadExtensions() { instanceOfferingExtensions = pluginRgty.getExtensionList(InstanceOfferingTagAllocatorExtensionPoint.class); diskOfferingExtensions = pluginRgty.getExtensionList(DiskOfferingTagAllocatorExtensionPoint.class); } @@ -48,6 +48,7 @@ public TagAllocatorFlow() { @Override public void allocate() { throwExceptionIfIAmTheFirstFlow(); + loadExtensions(); if (!instanceOfferingExtensions.isEmpty()) { SimpleQuery q = dbf.createQuery(SystemTagVO.class); diff --git a/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java b/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java index 0bbbe166d1c..60e19d32371 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java +++ b/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java @@ -11,10 +11,14 @@ import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.ClusterVO_; import org.zstack.header.host.*; import org.zstack.header.message.APIMessage; +import org.zstack.header.zone.ManagementNetworkIpVersionManager; import org.zstack.utils.ShellResult; import org.zstack.utils.ShellUtils; +import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; import static org.zstack.core.Platform.argerr; @@ -28,12 +32,19 @@ * To change this template use File | Settings | File Templates. */ public class HostApiInterceptor implements ApiMessageInterceptor { + private static final String INVALID_MANAGEMENT_IP_ERROR = + "managementIp[%s] is not a valid IPv4 address, IPv6 address, or hostname"; + private static final String RESERVED_MANAGEMENT_IPV6_ERROR = + "managementIp[%s] is an IPv6 address that cannot be used as a management address"; + @Autowired private CloudBus bus; @Autowired private ErrorFacade errf; @Autowired private DatabaseFacade dbf; + @Autowired + private ManagementNetworkIpVersionManager managementNetworkIpVersionManager; private void setServiceId(APIMessage msg) { if (msg instanceof HostMessage) { @@ -112,18 +123,70 @@ private void validate(APIDeleteHostMsg msg) { private void validate(APIUpdateHostMsg msg) { if (msg.getManagementIp() != null) { + msg.setManagementIp(validateManagementEndpoint(msg.getManagementIp())); + SimpleQuery q = dbf.createQuery(HostVO.class); q.add(HostVO_.managementIp, Op.EQ, msg.getManagementIp()); if (q.isExists()) { throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_COMPUTE_HOST_10112, "there has been a host having managementIp[%s]", msg.getManagementIp())); } + + String zoneUuid = Q.New(HostVO.class) + .select(HostVO_.zoneUuid) + .eq(HostVO_.uuid, msg.getUuid()) + .findValue(); + managementNetworkIpVersionManager.validateEndpointInZone(zoneUuid, msg.getManagementIp(), + "host", msg.getUuid(), ORG_ZSTACK_COMPUTE_HOST_10130); } } private void validate(APIAddHostMsg msg) { - if (!NetworkUtils.isIpv4Address(msg.getManagementIp()) && !NetworkUtils.isHostname(msg.getManagementIp())) { - throw new ApiMessageInterceptionException(argerr(ORG_ZSTACK_COMPUTE_HOST_10113, "managementIp[%s] is neither an IPv4 address nor a valid hostname", msg.getManagementIp())); + validateManagementEndpoint(msg); + String zoneUuid = Q.New(ClusterVO.class) + .select(ClusterVO_.zoneUuid) + .eq(ClusterVO_.uuid, msg.getClusterUuid()) + .findValue(); + managementNetworkIpVersionManager.validateEndpointInZone(zoneUuid, msg.getManagementIp(), + "host", msg.getName(), ORG_ZSTACK_COMPUTE_HOST_10130); + } + + static void validateManagementEndpoint(APIAddHostMsg msg) { + String managementIp = msg.getManagementIp(); + msg.setManagementIp(validateManagementEndpoint(managementIp)); + } + + static String validateManagementEndpoint(String managementIp) { + if (IPv6NetworkUtils.isIpv6Address(managementIp)) { + if (!IPv6NetworkUtils.isValidManagementIpv6Address(managementIp)) { + throw new ApiMessageInterceptionException(argerr( + ORG_ZSTACK_COMPUTE_HOST_10129, + RESERVED_MANAGEMENT_IPV6_ERROR, + managementIp)); + } + } else if (!isValidManagementEndpoint(managementIp)) { + throw new ApiMessageInterceptionException(argerr( + ORG_ZSTACK_COMPUTE_HOST_10128, + INVALID_MANAGEMENT_IP_ERROR, + managementIp)); } + + if (IPv6NetworkUtils.isIpv6Address(managementIp)) { + return IPv6NetworkUtils.getIpv6AddressCanonicalString(managementIp); + } + + return managementIp; + } + + static String getManagementEndpointValidationErrorCode(String managementIp) { + if (IPv6NetworkUtils.isIpv6Address(managementIp)) { + return IPv6NetworkUtils.isValidManagementIpv6Address(managementIp) ? null : ORG_ZSTACK_COMPUTE_HOST_10129; + } + + return isValidManagementEndpoint(managementIp) ? null : ORG_ZSTACK_COMPUTE_HOST_10128; + } + + private static boolean isValidManagementEndpoint(String endpoint) { + return IPv6NetworkUtils.isValidManagementEndpoint(endpoint); } private void validate(APIChangeHostStateMsg msg){ diff --git a/compute/src/main/java/org/zstack/compute/host/HostBase.java b/compute/src/main/java/org/zstack/compute/host/HostBase.java index 919d92631fc..df388331a89 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostBase.java +++ b/compute/src/main/java/org/zstack/compute/host/HostBase.java @@ -188,6 +188,8 @@ protected void handleApiMessage(APIMessage msg) { handle((APIPowerResetHostMsg) msg); } else if (msg instanceof APIGetHostPowerStatusMsg) { handle((APIGetHostPowerStatusMsg) msg); + } else if (msg instanceof APIGetBlockDevicesMsg) { + handle((APIGetBlockDevicesMsg) msg); } else { bus.dealWithUnknownMessage(msg); } @@ -214,6 +216,27 @@ public void run(MessageReply reply) { }); } + private void handle(APIGetBlockDevicesMsg msg) { + APIGetBlockDevicesEvent event = new APIGetBlockDevicesEvent(msg.getId()); + GetBlockDevicesOnHostMsg gmsg = new GetBlockDevicesOnHostMsg(); + gmsg.setHostUuid(msg.getHostUuid()); + gmsg.setIncludeInUse(msg.isIncludeInUse()); + bus.makeTargetServiceIdByResourceUuid(gmsg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.send(gmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + event.setSuccess(false); + event.setError(reply.getError()); + } else { + GetBlockDevicesOnHostReply r = reply.castReply(); + event.setBlockDevices(r.getBlockDevices()); + } + bus.publish(event); + } + }); + } + private void handle(APIPowerResetHostMsg msg) { final APIPowerResetHostEvent event = new APIPowerResetHostEvent(msg.getId()); RebootHostMsg rebootHostMsg = new RebootHostMsg(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java index 3059e9dfc19..8993b278e9b 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java @@ -6,7 +6,6 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.allocator.*; @@ -15,7 +14,6 @@ import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostInventory; import org.zstack.header.host.HostVO; @@ -24,8 +22,6 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkInventory; -import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO; -import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO_; import org.zstack.header.vm.*; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.utils.CollectionUtils; @@ -162,6 +158,7 @@ public void run(final FlowTrigger chain, Map data) { } AllocateHostMsg msg = this.prepareMsg(spec); + extEmitter.beforeVmAllocateHost(msg, spec); bus.send(msg, new CloudBusCallBack(chain) { @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java index 98f39b01372..d43d293d5b2 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java @@ -92,6 +92,7 @@ public String call(L3NetworkInventory arg) { msg.setAvoidHostUuids(spec.getAvoidHostUuids()); amsg = msg; + extEmitter.beforeVmAllocateHost(amsg, spec); bus.send(amsg, new CloudBusCallBack(chain) { @Override public void run(MessageReply reply) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java index 5b054dede75..6a40c15c34b 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java @@ -33,10 +33,8 @@ public class VmCreateOnHypervisorFlow implements Flow { @Autowired private EventFacade evtf; - private final List exts = pluginRgty.getExtensionList(VmBeforeCreateOnHypervisorExtensionPoint.class); - private void fireExtensions(VmInstanceSpec spec) { - for (VmBeforeCreateOnHypervisorExtensionPoint ext : exts) { + for (VmBeforeCreateOnHypervisorExtensionPoint ext : pluginRgty.getExtensionList(VmBeforeCreateOnHypervisorExtensionPoint.class)) { ext.beforeCreateVmOnHypervisor(spec); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java index 332314056b9..27166041769 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java @@ -337,6 +337,10 @@ protected VmInstanceVO changeVmStateInDb(VmInstanceStateEvent stateEvent) { } protected VmInstanceVO changeVmStateInDb(VmInstanceStateEvent stateEvent, Runnable runnable) { + return changeVmStateInDb(stateEvent, runnable, null); + } + + protected VmInstanceVO changeVmStateInDb(VmInstanceStateEvent stateEvent, Runnable runnable, String stateChangeSource) { VmInstanceState bs = self.getState(); final VmInstanceState state = self.getState().nextState(stateEvent); @@ -385,6 +389,7 @@ protected void scripts() { data.setVmUuid(self.getUuid()); data.setOldState(bs.toString()); data.setNewState(state.toString()); + data.setStateChangeSource(stateChangeSource); data.setInventory(getSelfInventory()); evtf.fire(VmCanonicalEvents.VM_FULL_STATE_CHANGED_PATH, data); @@ -1024,17 +1029,7 @@ public void done(ErrorCodeList errorCodeList) { String hostUuid = self.getHostUuid(); String suspectHostUuid = StringUtils.trimToNull(hostUuid); String peerHostUuid = StringUtils.trimToNull(msg.getAccessiblePeerHostUuid()); - UpdateQuery sql = SQL.New(VmInstanceVO.class) - .eq(VmInstanceVO_.uuid, self.getUuid()) - .set(VmInstanceVO_.state, VmInstanceState.Stopped) - .set(VmInstanceVO_.hostUuid, null); - - if (hostUuid != null) { - sql.set(VmInstanceVO_.lastHostUuid, hostUuid); - } - - sql.update(); - refreshVO(); + changeVmStateInDb(VmInstanceStateEvent.stopped, null, HaStartVmInstanceMsg.class.getName()); if (suspectHostUuid == null) { logger.debug(String.format("HA-start vm[%s]: skip creating pre-fence tag because suspect host is absent", self.getUuid())); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java index 78be6365828..21105efc5eb 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java @@ -6,6 +6,7 @@ import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.Component; +import org.zstack.header.allocator.AllocateHostMsg; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.WhileDoneCompletion; @@ -52,6 +53,7 @@ public class VmInstanceExtensionPointEmitter implements Component { private List vmNicChangeStateExtensionPoints; private List sshKeyPairAssociateExtensionPoints; private List afterUpdateVmNicMacExtensionPoints; + private List beforeVmAllocateHostExtensions; public List handleSystemTag(String vmUuid, List tags){ List errorCodes = new ArrayList<>(); @@ -614,6 +616,10 @@ public void cloneSshKeyPairsToVm(String originVmUuid, String destVmUuid) { }); } + public void beforeVmAllocateHost(AllocateHostMsg msg, VmInstanceSpec spec) { + CollectionUtils.safeForEach(beforeVmAllocateHostExtensions, ext -> ext.beforeVmAllocateHost(msg, spec)); + } + private void populateExtensions() { VmInstanceBeforeStartExtensions = pluginRgty.getExtensionList(VmInstanceBeforeStartExtensionPoint.class); VmInstanceResumeExtensionPoints = pluginRgty.getExtensionList(VmInstanceResumeExtensionPoint.class); @@ -632,6 +638,7 @@ private void populateExtensions() { vmNicChangeStateExtensionPoints = pluginRgty.getExtensionList(VmNicChangeStateExtensionPoint.class); sshKeyPairAssociateExtensionPoints = pluginRgty.getExtensionList(SshKeyPairAssociateExtensionPoint.class); afterUpdateVmNicMacExtensionPoints = pluginRgty.getExtensionList(AfterUpdateVmNicMacExtensionPoint.class); + beforeVmAllocateHostExtensions = pluginRgty.getExtensionList(BeforeVmAllocateHostExtensionPoint.class); } @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java index bbdb2978036..dbf1b574e35 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java @@ -25,8 +25,9 @@ public class VmInstantiateResourceForChangeImageFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private final List extensions = pluginRgty.getExtensionList(ChangeVmImageExtensionPoint.class); - + private List getExtensions() { + return pluginRgty.getExtensionList(ChangeVmImageExtensionPoint.class); + } private void runExtensions(final Iterator it, final VmInstanceSpec spec, final FlowTrigger chain) { if (!it.hasNext()) { @@ -53,6 +54,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + List extensions = getExtensions(); for (ChangeVmImageExtensionPoint extp : extensions) { try { extp.preBeforeInstantiateVmResource(spec); @@ -89,6 +91,6 @@ public void fail(ErrorCode errorCode) { @Override public void rollback(FlowRollback chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - rollbackExtensions(extensions.iterator(), spec, chain); + rollbackExtensions(getExtensions().iterator(), spec, chain); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java index e6a7f14c34d..a5f8e46bd54 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java @@ -28,11 +28,13 @@ public class VmInstantiateResourcePostFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private final List extensions = pluginRgty.getExtensionList(PostVmInstantiateResourceExtensionPoint.class); - + private List getExtensions() { + return pluginRgty.getExtensionList(PostVmInstantiateResourceExtensionPoint.class); + } public void run(FlowTrigger trigger, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + List extensions = getExtensions(); for (PostVmInstantiateResourceExtensionPoint ext : extensions) { ext.postBeforeInstantiateVmResource(spec); } @@ -64,7 +66,7 @@ public void fail(ErrorCode errorCode) { @Override public void rollback(FlowRollback trigger, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - rollbackExtensions(extensions.iterator(), spec, trigger); + rollbackExtensions(getExtensions().iterator(), spec, trigger); } private void rollbackExtensions(final Iterator iterator, final VmInstanceSpec spec, final FlowRollback trigger) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java index 4c7b6eee38f..4f4f7e6ff63 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java @@ -29,8 +29,9 @@ public class VmInstantiateResourcePreFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private final List extensions = pluginRgty.getExtensionList(PreVmInstantiateResourceExtensionPoint.class); - + private List getExtensions() { + return pluginRgty.getExtensionList(PreVmInstantiateResourceExtensionPoint.class); + } private void runExtensions(final Iterator it, final VmInstanceSpec spec, final FlowTrigger chain) { if (!it.hasNext()) { @@ -61,6 +62,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + List extensions = getExtensions(); for (PreVmInstantiateResourceExtensionPoint extp : extensions) { try { extp.preBeforeInstantiateVmResource(spec); @@ -97,6 +99,6 @@ public void fail(ErrorCode errorCode) { @Override public void rollback(FlowRollback chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - rollbackExtensions(extensions.iterator(), spec, chain); + rollbackExtensions(getExtensions().iterator(), spec, chain); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicLifecycleManager.java b/compute/src/main/java/org/zstack/compute/vm/VmNicLifecycleManager.java index 2a7348c416e..0721ca02de3 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmNicLifecycleManager.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicLifecycleManager.java @@ -8,7 +8,6 @@ import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.SysErrors; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.vm.*; import org.zstack.utils.Utils; @@ -17,6 +16,8 @@ import java.util.*; import java.util.stream.Collectors; +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.*; + public class VmNicLifecycleManager implements PreVmInstantiateResourceExtensionPoint, VmReleaseResourceExtensionPoint, @@ -68,7 +69,8 @@ private void runSetup(VmNicLifecycleContext context, Iterator it, try { nics = filterNics(ext, allNics); } catch (RuntimeException e) { - completion.fail(Platform.err(SysErrors.OPERATION_ERROR.toString(), SysErrors.OPERATION_ERROR, "%s", e.getMessage())); + completion.fail(Platform.operr(ORG_ZSTACK_COMPUTE_VM_10333, + "vm nic lifecycle pre-migration failed while selecting applicable NICs: %s", e.getMessage())); return; } if (nics.isEmpty()) { @@ -141,7 +144,7 @@ public void fail(ErrorCode errorCode) { } }); } catch (Throwable t) { - completion.fail(Platform.err(SysErrors.OPERATION_ERROR.toString(), SysErrors.OPERATION_ERROR, + completion.fail(Platform.operr(ORG_ZSTACK_COMPUTE_VM_10334, "%s.preMigrate(src=%s, dest=%s) threw exception: %s", ext.getClass().getSimpleName(), srcHostUuid, destHostUuid, t.getMessage())); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java index a57b93acde1..119ffdb74f5 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java @@ -26,9 +26,10 @@ public class VmReleaseResourceFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - - private final List extensions = pluginRgty.getExtensionList(VmReleaseResourceExtensionPoint.class); + private List getExtensions() { + return pluginRgty.getExtensionList(VmReleaseResourceExtensionPoint.class); + } private void fireExtensions(final Iterator it, final VmInstanceSpec spec, final Map ctx, final FlowTrigger chain) { if (!it.hasNext()) { @@ -53,7 +54,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger chain, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - fireExtensions(extensions.iterator(), spec, data, chain); + fireExtensions(getExtensions().iterator(), spec, data, chain); } @Override diff --git a/compute/src/main/java/org/zstack/compute/zone/ManagementNetworkIpVersionManagerImpl.java b/compute/src/main/java/org/zstack/compute/zone/ManagementNetworkIpVersionManagerImpl.java new file mode 100644 index 00000000000..7117791bfb4 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/zone/ManagementNetworkIpVersionManagerImpl.java @@ -0,0 +1,145 @@ +package org.zstack.compute.zone; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.tag.SystemTagInventory; +import org.zstack.header.zone.ManagementNetworkIpVersionManager; +import org.zstack.header.zone.ManagementNetworkIpVersionResourceExtensionPoint; +import org.zstack.header.zone.ZoneVO; +import org.zstack.utils.network.ManagementNetworkIpVersionUtils; + +import java.util.List; +import java.util.Map; + +import static org.zstack.core.Platform.argerr; +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.ORG_ZSTACK_COMPUTE_ZONE_10004; +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.ORG_ZSTACK_COMPUTE_ZONE_10005; +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.ORG_ZSTACK_COMPUTE_ZONE_10006; +import static org.zstack.utils.clouderrorcode.CloudOperationsErrorCode.ORG_ZSTACK_COMPUTE_ZONE_10007; + +public class ManagementNetworkIpVersionManagerImpl implements ManagementNetworkIpVersionManager { + private static final String DEFAULT_ZONE_IP_VERSION = ManagementNetworkIpVersionUtils.IPV4; + private static final String HOST_RESOURCE_TYPE = "host"; + private static final String MISMATCH_ERROR = + "%s[%s] uses %s endpoint[%s], but zone[uuid:%s] management network ipVersion is %s"; + + @Autowired + private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; + + @Override + public void validateEndpointInZone(String zoneUuid, String endpoint, String resourceType, String resourceIdentity, String errorCode) { + if (zoneUuid == null || endpoint == null) { + return; + } + + validateEndpointMatchesIpVersion(zoneUuid, getZoneIpVersion(zoneUuid), endpoint, resourceType, resourceIdentity, errorCode); + } + + @Override + public void validateEndpointMatchesIpVersion(String zoneUuid, String ipVersion, String endpoint, + String resourceType, String resourceIdentity, String errorCode) { + if (zoneUuid == null || ipVersion == null || endpoint == null) { + return; + } + + if (ManagementNetworkIpVersionUtils.isIpv6LinkLocalEndpoint(endpoint)) { + throw new ApiMessageInterceptionException(argerr( + ORG_ZSTACK_COMPUTE_ZONE_10007, + "%s[%s] uses IPv6 link-local endpoint[%s], which is not supported for zone[uuid:%s] management network", + resourceType, resourceIdentity, endpoint, zoneUuid)); + } + + String endpointIpVersion = ManagementNetworkIpVersionUtils.getEndpointIpVersion(endpoint); + if (endpointIpVersion == null || endpointIpVersion.equals(ipVersion)) { + return; + } + + throw new ApiMessageInterceptionException(argerr(errorCode, MISMATCH_ERROR, + resourceType, resourceIdentity, endpointIpVersion, endpoint, zoneUuid, ipVersion)); + } + + @Override + public String getZoneIpVersion(String zoneUuid) { + Map tokens = ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.getTokensByResourceUuid(zoneUuid); + if (tokens == null) { + return DEFAULT_ZONE_IP_VERSION; + } + + return ManagementNetworkIpVersionUtils.normalizeIpVersion( + tokens.get(ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION_TOKEN)); + } + + @Override + public void validateZoneCompatibleWithExistingResources(String zoneUuid, String ipVersion) { + validateExistingHosts(zoneUuid, ipVersion); + for (ManagementNetworkIpVersionResourceExtensionPoint ext : + pluginRgty.getExtensionList(ManagementNetworkIpVersionResourceExtensionPoint.class)) { + ext.validateExistingResourcesInZone(zoneUuid, ipVersion); + } + } + + public void validateZoneIpVersionTag(String resourceUuid, String systemTag) { + validateZoneIpVersionTag(resourceUuid, systemTag, null); + } + + public void validateZoneIpVersionTag(String resourceUuid, String systemTag, String excludedTagUuid) { + validateZoneIpVersionTagValue(resourceUuid, systemTag); + validateZoneHasNoOtherIpVersionTag(resourceUuid, excludedTagUuid); + } + + public void validateZoneIpVersionTagValue(String resourceUuid, String systemTag) { + if (!ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.isMatch(systemTag)) { + return; + } + + if (!dbf.isExist(resourceUuid, ZoneVO.class)) { + return; + } + + String ipVersion = ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.getTokenByTag( + systemTag, + ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION_TOKEN); + String normalizedIpVersion = ManagementNetworkIpVersionUtils.normalizeIpVersion(ipVersion); + if (normalizedIpVersion == null) { + throw new ApiMessageInterceptionException(argerr( + ORG_ZSTACK_COMPUTE_ZONE_10004, + "management network ipVersion[%s] is invalid, allowed values are [%s, %s]", + ipVersion, + ManagementNetworkIpVersionUtils.IPV4, + ManagementNetworkIpVersionUtils.IPV6)); + } + + validateZoneCompatibleWithExistingResources(resourceUuid, normalizedIpVersion); + } + + private void validateZoneHasNoOtherIpVersionTag(String zoneUuid, String excludedTagUuid) { + for (SystemTagInventory tag : ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.getTagInventories(zoneUuid)) { + if (excludedTagUuid != null && excludedTagUuid.equals(tag.getUuid())) { + continue; + } + + throw new ApiMessageInterceptionException(argerr( + ORG_ZSTACK_COMPUTE_ZONE_10006, + "zone[uuid:%s] already has management network ipVersion system tag[%s], update or delete it before creating another one", + zoneUuid, tag.getTag())); + } + } + + private void validateExistingHosts(String zoneUuid, String ipVersion) { + List hosts = Q.New(HostVO.class) + .eq(HostVO_.zoneUuid, zoneUuid) + .list(); + + for (HostVO host : hosts) { + validateEndpointMatchesIpVersion(zoneUuid, ipVersion, host.getManagementIp(), + HOST_RESOURCE_TYPE, host.getUuid(), ORG_ZSTACK_COMPUTE_ZONE_10005); + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java index e450fa75f9b..1537ed30318 100755 --- a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java @@ -20,9 +20,13 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; +import org.zstack.header.tag.AbstractSystemTagOperationJudger; +import org.zstack.header.tag.SystemTagInventory; +import org.zstack.header.tag.SystemTagValidator; import org.zstack.header.zone.*; import org.zstack.search.SearchQuery; import org.zstack.tag.TagManager; +import org.zstack.utils.network.ManagementNetworkIpVersionUtils; import org.zstack.utils.ObjectUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -51,9 +55,13 @@ public class ZoneManagerImpl extends AbstractService implements ZoneManager { private TagManager tagMgr; @Autowired private ThreadFacade thdf; + @Autowired + private ManagementNetworkIpVersionManagerImpl managementNetworkIpVersionManager; private Map zoneFactories = Collections.synchronizedMap(new HashMap()); private static final Set allowedMessageAfterSoftDeletion = new HashSet(); + private static final String DEFAULT_MANAGEMENT_NETWORK_IP_VERSION_TAG = + String.format("managementNetwork::ipVersion::%s", ManagementNetworkIpVersionUtils.IPV4); static { allowedMessageAfterSoftDeletion.add(ZoneDeletionMsg.class); @@ -156,10 +164,22 @@ protected void scripts() { }.execute(); tagMgr.createTagsFromAPICreateMessage(msg, finalVO.getUuid(), ZoneVO.class.getSimpleName()); + createDefaultManagementNetworkIpVersionTagIfAbsent(finalVO.getUuid()); return ZoneInventory.valueOf(finalVO); } + private void createDefaultManagementNetworkIpVersionTagIfAbsent(String zoneUuid) { + if (ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.getTagInventory(zoneUuid) != null) { + return; + } + + tagMgr.createNonInherentSystemTag( + zoneUuid, + DEFAULT_MANAGEMENT_NETWORK_IP_VERSION_TAG, + ZoneVO.class.getSimpleName()); + } + private void createZone(APICreateZoneMsg msg, ReturnValueCompletion completion) { if (msg.getDefault() == null || !msg.getDefault()) { completion.success(createZoneFromApiMessage(msg)); @@ -225,6 +245,31 @@ private void populateExtensions() { @Override public boolean start() { populateExtensions(); + ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.installValidator(new SystemTagValidator() { + @Override + public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { + managementNetworkIpVersionManager.validateZoneIpVersionTagValue(resourceUuid, systemTag); + } + }); + ZoneSystemTags.MANAGEMENT_NETWORK_IP_VERSION.installJudger(new AbstractSystemTagOperationJudger() { + @Override + public void tagPreCreated(SystemTagInventory tag) { + managementNetworkIpVersionManager.validateZoneIpVersionTag( + tag.getResourceUuid(), tag.getTag()); + } + + @Override + public void tagPreUpdated(SystemTagInventory old, SystemTagInventory newTag) { + managementNetworkIpVersionManager.validateZoneIpVersionTag( + newTag.getResourceUuid(), newTag.getTag(), old.getUuid()); + } + + @Override + public void tagPreDeleted(SystemTagInventory tag) { + managementNetworkIpVersionManager.validateZoneCompatibleWithExistingResources( + tag.getResourceUuid(), ManagementNetworkIpVersionUtils.IPV4); + } + }); return true; } diff --git a/compute/src/main/java/org/zstack/compute/zone/ZoneSystemTags.java b/compute/src/main/java/org/zstack/compute/zone/ZoneSystemTags.java index e2d68ff9bd8..8de485355e1 100755 --- a/compute/src/main/java/org/zstack/compute/zone/ZoneSystemTags.java +++ b/compute/src/main/java/org/zstack/compute/zone/ZoneSystemTags.java @@ -10,4 +10,9 @@ public class ZoneSystemTags { public static PatternedSystemTag HOST_RESERVED_CPU_CAPACITY = new PatternedSystemTag("host::reservedCpu::{capacity}", ZoneVO.class); public static PatternedSystemTag HOST_RESERVED_MEMORY_CAPACITY = new PatternedSystemTag("host::reservedMemory::{capacity}", ZoneVO.class); + public static final String MANAGEMENT_NETWORK_IP_VERSION_TOKEN = "ipVersion"; + public static PatternedSystemTag MANAGEMENT_NETWORK_IP_VERSION = new PatternedSystemTag( + String.format("managementNetwork::ipVersion::{%s}", MANAGEMENT_NETWORK_IP_VERSION_TOKEN), + ZoneVO.class + ); } diff --git a/conf/db/upgrade/V5.5.28__schema.sql b/conf/db/upgrade/V5.5.28__schema.sql index e69de29bb2d..95db09ddf99 100644 --- a/conf/db/upgrade/V5.5.28__schema.sql +++ b/conf/db/upgrade/V5.5.28__schema.sql @@ -0,0 +1,221 @@ +-- Do not filter by architecture here. The upgrade preserves previous Windows VM behavior across all architectures; +-- current kvmagent consumption is still gated by host CPU architecture at start time. +INSERT INTO `zstack`.`ResourceConfigVO` (`uuid`, `name`, `description`, `category`, `value`, `resourceUuid`, `resourceType`, `lastOpDate`, `createDate`) +SELECT REPLACE(UUID(), '-', ''), 'vm.cpu.hardwareVirtualization', 'enable or disable hardware virtualization feature in Windows guest cpuid', + 'kvm', 'true', vm.`uuid`, 'VmInstanceVO', NOW(), NOW() +FROM `zstack`.`VmInstanceVO` vm +WHERE (vm.`platform` IN ('Windows', 'WindowsVirtio') + OR LOWER(IFNULL(vm.`guestOsType`, '')) LIKE '%windows%') + AND NOT EXISTS ( + SELECT 1 + FROM `zstack`.`ResourceConfigVO` rc + WHERE rc.`resourceUuid` = vm.`uuid` + AND rc.`category` = 'kvm' + AND rc.`name` = 'vm.cpu.hardwareVirtualization' + ); + +ALTER TABLE `zstack`.`DRSVmMigrationActivityVO` MODIFY COLUMN `result` TEXT DEFAULT NULL; + +UPDATE `zstack`.`PciDeviceMdevSpecRefVO` keepRef +JOIN ( + SELECT `pciDeviceUuid`, `mdevSpecUuid`, MAX(`id`) AS `keepId`, MAX(`effective`) AS `effective` + FROM `zstack`.`PciDeviceMdevSpecRefVO` + GROUP BY `pciDeviceUuid`, `mdevSpecUuid` +) groupedRef ON keepRef.`id` = groupedRef.`keepId` +SET keepRef.`effective` = groupedRef.`effective`; + +DELETE duplicateRef FROM `zstack`.`PciDeviceMdevSpecRefVO` duplicateRef +JOIN `zstack`.`PciDeviceMdevSpecRefVO` keepRef + ON duplicateRef.`pciDeviceUuid` = keepRef.`pciDeviceUuid` + AND duplicateRef.`mdevSpecUuid` = keepRef.`mdevSpecUuid` + AND duplicateRef.`id` < keepRef.`id`; + +UPDATE `zstack`.`PciDeviceMdevSpecRefVO` ref +JOIN ( + SELECT activeRef.`id` + FROM `zstack`.`PciDeviceMdevSpecRefVO` activeRef + JOIN ( + SELECT `pciDeviceUuid` + FROM `zstack`.`PciDeviceMdevSpecRefVO` + WHERE `effective` = 1 + GROUP BY `pciDeviceUuid` + HAVING COUNT(*) > 1 + ) duplicatedPci ON activeRef.`pciDeviceUuid` = duplicatedPci.`pciDeviceUuid` + WHERE activeRef.`effective` = 1 + AND NOT EXISTS ( + SELECT 1 + FROM `zstack`.`MdevDeviceVO` mdev + WHERE mdev.`parentUuid` = activeRef.`pciDeviceUuid` + AND mdev.`mdevSpecUuid` = activeRef.`mdevSpecUuid` + ) +) staleRef ON ref.`id` = staleRef.`id` +SET ref.`effective` = 0; + +UPDATE `zstack`.`PciDeviceMdevSpecRefVO` oldRef +JOIN `zstack`.`PciDeviceMdevSpecRefVO` newRef + ON oldRef.`pciDeviceUuid` = newRef.`pciDeviceUuid` + AND oldRef.`effective` = 1 + AND newRef.`effective` = 1 + AND oldRef.`id` < newRef.`id` +SET oldRef.`effective` = 0; + +DROP PROCEDURE IF EXISTS addPciDeviceMdevSpecRefUniqueKey; +DELIMITER $$ +CREATE PROCEDURE addPciDeviceMdevSpecRefUniqueKey() +BEGIN + DECLARE index_count INT DEFAULT 0; + + SELECT COUNT(*) INTO index_count + FROM information_schema.statistics + WHERE table_schema = 'zstack' + AND table_name = 'PciDeviceMdevSpecRefVO' + AND index_name = 'ukPciDeviceMdevSpecRefVOPciUuidMdevSpecUuid'; + + IF index_count < 1 THEN + ALTER TABLE `zstack`.`PciDeviceMdevSpecRefVO` + ADD UNIQUE KEY `ukPciDeviceMdevSpecRefVOPciUuidMdevSpecUuid` (`pciDeviceUuid`, `mdevSpecUuid`); + END IF; + + SELECT CURTIME(); +END $$ +DELIMITER ; +CALL addPciDeviceMdevSpecRefUniqueKey(); +DROP PROCEDURE IF EXISTS addPciDeviceMdevSpecRefUniqueKey; + +-- ZCF-4158: Store SCIM event application state. +CREATE TABLE IF NOT EXISTS `zstack`.`ScimEventVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'uuid', + `clientId` varchar(128) NOT NULL DEFAULT 'default', + `eventId` varchar(255) NOT NULL, + `resourceType` varchar(64) NOT NULL, + `resourceId` varchar(255) NOT NULL, + `operation` varchar(32) NOT NULL, + `status` varchar(32) NOT NULL, + `payloadHash` varchar(128) DEFAULT NULL, + `errorMessage` text DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`uuid`), + UNIQUE KEY `ukScimEventVOClientEvent` (`clientId`, `eventId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `HostCacheStoreVO` ( + `uuid` VARCHAR(32) NOT NULL, + `hostUuid` VARCHAR(32) NOT NULL, + `name` VARCHAR(255) DEFAULT NULL, + `description` VARCHAR(2048) DEFAULT NULL, + `mountPoint` VARCHAR(255) DEFAULT NULL, + `devices` TEXT, + `state` VARCHAR(32) NOT NULL, + `status` VARCHAR(32) NOT NULL, + `createDate` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostCacheStoreVOHostEO` + FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) + ON DELETE CASCADE + ) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `HostCacheStoreCapacityVO` ( + `uuid` VARCHAR(32) NOT NULL, + `totalCapacity` BIGINT NOT NULL DEFAULT 0, + `availableCapacity` BIGINT NOT NULL DEFAULT 0, + `allocated` BIGINT NOT NULL DEFAULT 0, + `dirty` BIGINT NOT NULL DEFAULT 0, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostCacheStoreCapacityVOHostCacheStoreVO` + FOREIGN KEY (`uuid`) REFERENCES `HostCacheStoreVO` (`uuid`) + ON DELETE CASCADE + ) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `VolumeCacheVO` ( + `uuid` VARCHAR(32) NOT NULL, + `volumeUuid` VARCHAR(32) NOT NULL, + `poolUuid` VARCHAR(32) DEFAULT NULL, + `installPath` VARCHAR(2048) DEFAULT NULL, + `cacheMode` VARCHAR(32) NOT NULL, + `status` VARCHAR(32) NOT NULL, + `createDate` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + UNIQUE KEY `uniVolumeCacheVOVolumeUuid` (`volumeUuid`), + CONSTRAINT `fkVolumeCacheVOVolumeEO` + FOREIGN KEY (`volumeUuid`) REFERENCES `VolumeEO` (`uuid`) + ON DELETE CASCADE, + CONSTRAINT `fkVolumeCacheVOPoolUuid` + FOREIGN KEY (`poolUuid`) REFERENCES `HostCacheStoreVO` (`uuid`) + ON DELETE SET NULL + ) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +-- ZCF-4419: Track resources synchronized from external identity sources. +CREATE TABLE IF NOT EXISTS `zstack`.`ResourceSourceRefVO` ( + `uuid` varchar(32) NOT NULL COMMENT 'uuid', + `resourceUuid` varchar(32) NOT NULL, + `resourceType` varchar(64) NOT NULL, + `sourceType` varchar(64) NOT NULL, + `sourceName` varchar(128) DEFAULT NULL, + `externalUuid` varchar(32) DEFAULT NULL, + `externalType` varchar(255) DEFAULT NULL, + `syncType` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`uuid`), + UNIQUE KEY `ukResourceSourceRefVOResourceSourceSync` (`resourceUuid`, `resourceType`, `sourceType`, `syncType`), + KEY `idxResourceSourceRefVOSourceSyncResourceType` (`sourceType`, `syncType`, `resourceType`), + KEY `idxResourceSourceRefVOResourceSync` (`resourceType`, `resourceUuid`, `syncType`), + KEY `idxResourceSourceRefVOSyncType` (`syncType`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP PROCEDURE IF EXISTS upgrade_vtep_ip_not_null; +DELIMITER $$ +CREATE PROCEDURE upgrade_vtep_ip_not_null() +BEGIN + IF EXISTS (SELECT 1 FROM `zstack`.`VtepVO` WHERE `vtepIp` IS NULL) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'VtepVO.vtepIp contains NULL values'; + END IF; + + IF EXISTS (SELECT 1 FROM `zstack`.`RemoteVtepVO` WHERE `vtepIp` IS NULL) THEN + SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'RemoteVtepVO.vtepIp contains NULL values'; + END IF; +END $$ +DELIMITER ; + +CALL upgrade_vtep_ip_not_null(); +DROP PROCEDURE IF EXISTS upgrade_vtep_ip_not_null; + +ALTER TABLE `zstack`.`VtepVO` MODIFY COLUMN `vtepIp` varchar(128) NOT NULL; +ALTER TABLE `zstack`.`RemoteVtepVO` MODIFY COLUMN `vtepIp` varchar(128) NOT NULL; + +INSERT INTO `zstack`.`SystemTagVO` (`uuid`, `resourceUuid`, `resourceType`, `inherent`, `type`, `tag`, `createDate`, `lastOpDate`) +SELECT REPLACE(UUID(), '-', ''), z.uuid, 'ZoneVO', 0, 'System', 'managementNetwork::ipVersion::ipv4', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP() +FROM `zstack`.`ZoneVO` z +WHERE NOT EXISTS ( + SELECT 1 + FROM `zstack`.`SystemTagVO` st + WHERE st.resourceUuid = z.uuid + AND st.resourceType = 'ZoneVO' + AND st.type = 'System' + AND st.tag LIKE 'managementNetwork::ipVersion::%' +); + +ALTER TABLE `zstack`.`ConsoleProxyAgentVO` ADD COLUMN `consoleProxyOverriddenIpv4` varchar(255) DEFAULT NULL; +ALTER TABLE `zstack`.`ConsoleProxyAgentVO` ADD COLUMN `consoleProxyOverriddenIpv6` varchar(255) DEFAULT NULL; + +ALTER TABLE `zstack`.`AlarmVO` ADD COLUMN `recoveryDuration` int unsigned DEFAULT NULL; +ALTER TABLE `zstack`.`AlarmVO` ADD COLUMN `recoveryThreshold` int unsigned DEFAULT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`AlarmResourceStateVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `alarmUuid` varchar(32) NOT NULL, + `identifyLabel` varchar(191) NOT NULL, + `resourceUuid` varchar(32) DEFAULT NULL, + `resourceType` varchar(256) DEFAULT NULL, + `status` varchar(32) NOT NULL, + `lastStatusChangeTime` bigint(20) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + UNIQUE KEY `ukAlarmUuidIdentifyLabel` (`alarmUuid`, `identifyLabel`, `resourceUuid`), + KEY `idxAlarmResourceStateVOresourceUuid` (`resourceUuid`), + CONSTRAINT `fkAlarmResourceStateVOAlarmVO` FOREIGN KEY (`alarmUuid`) REFERENCES `AlarmVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/deploydb.sh b/conf/deploydb.sh index 033da079954..c0d27e12d41 100755 --- a/conf/deploydb.sh +++ b/conf/deploydb.sh @@ -8,6 +8,16 @@ password="$2" host="$3" port="$4" zstack_user_password="$5" +mysql_host="$host" + +case "$mysql_host" in + \[*\]) mysql_host="${mysql_host#\[}"; mysql_host="${mysql_host%\]}" ;; +esac + +jdbc_host="$mysql_host" +case "$jdbc_host" in + *:*) jdbc_host="[$jdbc_host]" ;; +esac base=`dirname $0` @@ -30,7 +40,7 @@ if command -v greatdb &> /dev/null; then fi mysql_run() { - $MYSQL --user=$user --password=$password --host=$host --port=$port "$@" + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port "$@" } if command -v greatdb &> /dev/null; then @@ -67,7 +77,7 @@ mkdir -p $flyway_sql cp $base/db/V0.6__schema.sql $flyway_sql cp $base/db/upgrade/* $flyway_sql -url="jdbc:mysql://$host:$port/zstack" +url="jdbc:mysql://$jdbc_host:$port/zstack" bash $flyway -user=$user -password=$password -url=$url clean @@ -81,7 +91,7 @@ eval "rm -f $flyway_sql/*" cp $base/db/V0.6__schema_buildin_httpserver.sql $flyway_sql -url="jdbc:mysql://$host:$port/zstack_rest" +url="jdbc:mysql://$jdbc_host:$port/zstack_rest" bash $flyway -user=$user -password=$password -url=$url clean bash $flyway -user=$user -password=$password -url=$url migrate @@ -92,7 +102,7 @@ hostname=`hostname` [ -z $zstack_user_password ] && zstack_user_password='' if command -v greatdb &> /dev/null; then - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF drop user if exists zstack; drop user if exists zstack_rest; create user if not exists 'zstack'@'localhost' identified by "$zstack_user_password"; @@ -110,7 +120,7 @@ EOF else db_version=`$MYSQL --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` if [ $db_version -ge 10 ];then - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF drop user if exists zstack; drop user if exists zstack_rest; create user 'zstack' identified by "$zstack_user_password"; @@ -122,7 +132,7 @@ else flush privileges; EOF else - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF grant usage on *.* to 'zstack'@'localhost'; grant usage on *.* to 'zstack'@'%'; drop user zstack; @@ -137,4 +147,3 @@ EOF EOF fi fi - diff --git a/conf/deployuidb.sh b/conf/deployuidb.sh index 16a7e659576..cba144bdcad 100755 --- a/conf/deployuidb.sh +++ b/conf/deployuidb.sh @@ -6,6 +6,16 @@ password="$2" host="$3" port="$4" zstack_ui_db_password="$5" +mysql_host="$host" + +case "$mysql_host" in + \[*\]) mysql_host="${mysql_host#\[}"; mysql_host="${mysql_host%\]}" ;; +esac + +jdbc_host="$mysql_host" +case "$jdbc_host" in + *:*) jdbc_host="[$jdbc_host]" ;; +esac MYSQL='mysql' @@ -27,18 +37,18 @@ flyway_sql="$base/tools/flyway-3.2.1/sql/" # give grant option to the new management ip after `zstack-ctl change_ip` if command -v greatdb &> /dev/null; then $MYSQL --user=$user --password=$password --port=$port << EOF - grant all privileges on *.* to 'root'@"$host" with grant option; + grant all privileges on *.* to 'root'@"$mysql_host" with grant option; FLUSH PRIVILEGES; EOF else $MYSQL --user=$user --password=$password --port=$port << EOF - grant all privileges on *.* to 'root'@"$host" identified by "$password" with grant option; + grant all privileges on *.* to 'root'@"$mysql_host" identified by "$password" with grant option; FLUSH PRIVILEGES; EOF fi if command -v greatdb &> /dev/null; then - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF grant usage on *.* to 'root'@'localhost'; grant usage on *.* to 'root'@'%'; DROP DATABASE IF EXISTS zstack_ui; @@ -50,7 +60,7 @@ if command -v greatdb &> /dev/null; then flush privileges; EOF else - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF grant usage on *.* to 'root'@'localhost'; grant usage on *.* to 'root'@'%'; DROP DATABASE IF EXISTS zstack_ui; @@ -67,7 +77,7 @@ mkdir -p $flyway_sql ui_schema_path=`echo ~zstack`"/zstack-ui/tmp/WEB-INF/classes/db/migration/" if [ -d $ui_schema_path ]; then cp $ui_schema_path/* $flyway_sql - url="jdbc:mysql://$host:$port/zstack_ui" + url="jdbc:mysql://$jdbc_host:$port/zstack_ui" bash $flyway -user=$user -password=$password -url=$url clean bash $flyway -user=$user -password=$password -url=$url migrate eval "rm -f $flyway_sql/*" @@ -76,7 +86,7 @@ fi hostname=`hostname` if command -v greatdb &> /dev/null; then - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF drop user if exists zstack_ui; create user 'zstack_ui' identified by "$zstack_ui_db_password"; create user if not exists 'zstack_ui'@'localhost' identified by "$zstack_ui_db_password"; @@ -88,7 +98,7 @@ EOF else db_version=`$MYSQL --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` if [ $db_version -ge 10 ];then - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF drop user if exists zstack_ui; create user 'zstack_ui' identified by "$zstack_ui_db_password"; grant all privileges on zstack_ui.* to zstack_ui@'localhost' identified by "$zstack_ui_db_password"; @@ -96,7 +106,7 @@ else flush privileges; EOF else - $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + $MYSQL --user=$user --password=$password --host=$mysql_host --port=$port << EOF grant usage on *.* to 'zstack_ui'@'localhost'; grant usage on *.* to 'zstack_ui'@'%'; drop user zstack_ui; diff --git a/conf/globalConfig/kvm.xml b/conf/globalConfig/kvm.xml index 76d53a5453a..7decad013fc 100755 --- a/conf/globalConfig/kvm.xml +++ b/conf/globalConfig/kvm.xml @@ -226,6 +226,14 @@ java.lang.Boolean + + kvm + vm.cpu.hardwareVirtualization + enable or disable hardware virtualization feature in Windows guest cpuid + false + java.lang.Boolean + + kvm vm.hyperv.clock.feature diff --git a/conf/globalConfig/l2Network.xml b/conf/globalConfig/l2Network.xml index f6032411257..3c20b72b044 100644 --- a/conf/globalConfig/l2Network.xml +++ b/conf/globalConfig/l2Network.xml @@ -28,4 +28,11 @@ l2Network java.lang.Integer - \ No newline at end of file + + bridge.multicastQuerier + Enable multicast querier and snooping on linux bridge when creating l2 network bridge + true + l2Network + java.lang.Boolean + + diff --git a/conf/globalConfig/virutalRouter.xml b/conf/globalConfig/virutalRouter.xml index 36e3b30ef2c..e084e3f925b 100755 --- a/conf/globalConfig/virutalRouter.xml +++ b/conf/globalConfig/virutalRouter.xml @@ -21,6 +21,20 @@ virtualRouter java.lang.Integer + + dnsmasq.dnsForwardMax + The maximum number of concurrent DNS queries forwarded by dnsmasq on a virtual router. + 1000 + virtualRouter + java.lang.Integer + + + dnsmasq.cacheSize + The DNS cache size used by dnsmasq on a virtual router. + 10000 + virtualRouter + java.lang.Integer + ping.interval The interval management nodes ping the virtual router agents running virtual router VMs, in seconds diff --git a/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json b/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json index 3aeec70b44c..eb52bff974f 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-de-DE.json @@ -2871,6 +2871,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "Abrufen des Integritätspassworts aus der Datenbank fehlgeschlagen, da %s kein Integritätspasswort generiert", "ORG_ZSTACK_VHOST_KVM_10000": "vHostUser-Datenträger unterstützt nur den Virtio-Modus. Bitte überprüfen Sie, ob die Image-Plattform die erforderlichen Virtio-Treiber installiert hat.", "ORG_ZSTACK_VHOST_KVM_10001": "vHost-User-Datenträger unterstützt den Virtio-SCSI-Modus nicht; bitte deaktivieren Sie den Virtio-SCSI-Modus.", + "ORG_ZSTACK_VHOST_KVM_10002": "vhost-user-Datenträger kann nicht online angehängt werden: Bei der laufenden VM ist kein gemeinsam genutzter Speicher aktiviert. Fahren Sie die VM herunter und hängen Sie sie dann an, oder setzen Sie die globale Konfiguration 'generate.config.vhost.required' auf 'auto' oder 'true' und starten Sie die VM neu (dies deaktiviert Memory Overcommit für die VM).", "ORG_ZSTACK_NETWORK_L3_10029": "%s ist keine gültige IPv6-Adresse für die Cloud-Ressourcenkonfiguration", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough unterstützt nur die Verwendung auf einer VM, die in der Host-Umgebung ausgeführt wird.", "ORG_ZSTACK_ALIYUN_ECS_10019": "Nur administrative Benutzer können den Parameter [onlyZstack] auf false setzen.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json index 5c54d1fd80f..637997dc616 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-en_US.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-en_US.json @@ -448,6 +448,10 @@ "ORG_ZSTACK_STORAGE_CEPH_PRIMARY_10050": "Ceph ps[uuid\u003d%s] Root Pool Name Not Found", "ORG_ZSTACK_STORAGE_CEPH_PRIMARY_10052": "delete volume chain error, continue with volume deletion", "ORG_ZSTACK_COMPUTE_VM_10320": "VmInstanceStartExtensionPoint[%s] refuses to start virtual machine[uuid:%s] because %s", + "ORG_ZSTACK_COMPUTE_VM_10331": "VM NIC lifecycle setup failed while selecting applicable NICs: %s", + "ORG_ZSTACK_COMPUTE_VM_10332": "VM NIC lifecycle extension[%s] setup on host[uuid:%s] failed unexpectedly: %s", + "ORG_ZSTACK_COMPUTE_VM_10333": "VM NIC lifecycle pre-migration failed while selecting applicable NICs: %s", + "ORG_ZSTACK_COMPUTE_VM_10334": "VM NIC lifecycle extension[%s] pre-migration from host[uuid:%s] to host[uuid:%s] failed unexpectedly: %s", "ORG_ZSTACK_COMPUTE_HOST_10013": "networkInterface[name:%s] of instance[uuid:%s] cannot be found", "ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10008": "encryption %s[id:%s] failed: %s", "ORG_ZSTACK_CRYPTO_DATACRYPTO_SMP_10000": "the shared mount point primary storage[uuid:%s, name:%s] cannot find any available host within the attached compute clusters", @@ -2963,6 +2967,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "Get integrity password from database failed due to %s does not generate integrity password", "ORG_ZSTACK_VHOST_KVM_10000": "vHostUser disk only supports virtio mode. Please verify that the image platform has the necessary virtio drivers installed.", "ORG_ZSTACK_VHOST_KVM_10001": "vhost-user disk does not support virtio-scsi mode; please disable virtio-scsi mode.", + "ORG_ZSTACK_VHOST_KVM_10002": "Cannot attach vhost-user data volume online: the running VM does not have shared memory enabled. Either shut down the VM and then attach, or set the global config 'generate.config.vhost.required' to 'auto' or 'true' and restart the VM (this disables memory overcommit for the VM).", "ORG_ZSTACK_NETWORK_L3_10029": "%s is not a valid IPv6 address for cloud resource configuration", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough only supports usage on a VM running in the host environment.", "ORG_ZSTACK_ALIYUN_ECS_10019": "Only administrative users can set the parameter [onlyZstack] to false.", @@ -4179,6 +4184,8 @@ "ORG_ZSTACK_POLICYROUTE_10010": "NextHopIp must be in IPv4 format but found [%s]", "ORG_ZSTACK_CORE_REST_10012": "unable to retrieve %s within %sms", "ORG_ZSTACK_CORE_REST_10013": "kvmagent on host[uuid:%s] restarted at %s, pending HTTP call sent before %s aborted", + "ORG_ZSTACK_CORE_REST_10014": "Failed to handle REST API: %s", + "ORG_ZSTACK_CORE_REST_10015": "REST API request failed: %s", "ORG_ZSTACK_QUERY_10021": "field[%s] is not a primitive of the inventory %s; you cannot specify it in the parameter \u0027fields\u0027; valid fields are %s", "ORG_ZSTACK_NETWORK_SERVICE_FLAT_10034": "DHCP server IP [%s] already exists within L3 network [%s]", "ORG_ZSTACK_QUERY_10020": "entity metadata class[%s] lacks field[%s]", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json b/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json index b1ac5f6ba2c..00b52b1e03d 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-fr-FR.json @@ -2961,6 +2961,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "Échec de l'obtention du mot de passe d'intégrité de la base de données car %s ne génère pas de mot de passe d'intégrité", "ORG_ZSTACK_VHOST_KVM_10000": "Le disque vHostUser ne prend en charge que le mode virtio. Veuillez vérifier que la plateforme d'image dispose des pilotes virtio nécessaires.", "ORG_ZSTACK_VHOST_KVM_10001": "Le disque vhost-user ne prend pas en charge le mode virtio-scsi ; veuillez désactiver le mode virtio-scsi.", + "ORG_ZSTACK_VHOST_KVM_10002": "Impossible d’attacher le disque vhost-user en ligne : la VM en cours d’exécution n’a pas la mémoire partagée activée. Arrêtez la VM puis attachez, ou définissez la configuration globale « generate.config.vhost.required » sur « auto » ou « true » et redémarrez la VM (cela désactive la surallocation mémoire pour la VM).", "ORG_ZSTACK_NETWORK_L3_10029": "%s n'est pas une adresse IPv6 valide pour la configuration des ressources cloud", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough ne peut être utilisé que sur une machine virtuelle s'exécutant dans l'environnement hôte.", "ORG_ZSTACK_ALIYUN_ECS_10019": "Seuls les utilisateurs administratifs peuvent définir le paramètre [onlyZstack] sur false.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json b/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json index a1daa8a6768..4324b9a1774 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-id-ID.json @@ -2961,6 +2961,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "Gagal mendapatkan kata sandi integritas dari database karena %s tidak menghasilkan kata sandi integritas", "ORG_ZSTACK_VHOST_KVM_10000": "Disk vHostUser hanya mendukung mode virtio. Harap verifikasi bahwa platform gambar memiliki driver virtio yang diperlukan terinstal.", "ORG_ZSTACK_VHOST_KVM_10001": "Disk vhost-user tidak mendukung mode virtio-scsi; harap nonaktifkan mode virtio-scsi.", + "ORG_ZSTACK_VHOST_KVM_10002": "Tidak dapat memasang disk vhost-user secara online: VM yang berjalan tidak mengaktifkan shared memory. Matikan VM lalu pasang, atau atur konfigurasi global 'generate.config.vhost.required' ke 'auto' atau 'true' dan mulai ulang VM (ini menonaktifkan overcommit memori untuk VM).", "ORG_ZSTACK_NETWORK_L3_10029": "%s bukan alamat IPv6 yang valid untuk konfigurasi sumber daya cloud", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough hanya didukung untuk penggunaan pada VM yang berjalan di lingkungan host.", "ORG_ZSTACK_ALIYUN_ECS_10019": "Hanya pengguna administratif yang dapat menetapkan parameter [onlyZstack] ke false.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json b/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json index 7f8132b76de..307986d2224 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ja-JP.json @@ -2931,6 +2931,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "データベースから整合性パスワードの取得に失敗しました。%sが整合性パスワードを生成していないためです", "ORG_ZSTACK_VHOST_KVM_10000": "vHostUserディスクはvirtioモードのみをサポートします。イメージプラットフォームに必要なvirtioドライバーがインストールされていることを確認してください。", "ORG_ZSTACK_VHOST_KVM_10001": "vhost-userディスクはvirtio-scsiモードをサポートしません。virtio-scsiモードを無効にしてください。", + "ORG_ZSTACK_VHOST_KVM_10002": "vhost-userデータボリュームをオンラインでアタッチできません:実行中のVMで共有メモリが有効化されていません。VMをシャットダウンしてからアタッチするか、グローバル設定 generate.config.vhost.required を auto または true に設定してVMを再起動してください(VMのメモリオーバーコミットが無効になります)。", "ORG_ZSTACK_NETWORK_L3_10029": "%sはクラウドリソース構成の有効なIPv6アドレスではありません", "ORG_ZSTACK_USBDEVICE_10005": "PassThroughはホスト環境で実行されているVMでのみ使用できます。", "ORG_ZSTACK_ALIYUN_ECS_10019": "パラメータ[onlyZstack]をfalseに設定できるのは管理者のみです。", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json b/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json index b8188ee11b5..e9f65cdc59f 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ko-KR.json @@ -2871,6 +2871,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "데이터베이스에서 무결성 비밀번호를 가져오지 못했습니다. %s이(가) 무결성 비밀번호를 생성하지 않았기 때문입니다.", "ORG_ZSTACK_VHOST_KVM_10000": "vHostUser 디스크는 virtio 모드만 지원합니다. 이미지 플랫폼에 필요한 virtio 드라이버가 설치되어 있는지 확인하십시오.", "ORG_ZSTACK_VHOST_KVM_10001": "vhost-user 디스크는 virtio-scsi 모드를 지원하지 않습니다. virtio-scsi 모드를 비활성화하십시오.", + "ORG_ZSTACK_VHOST_KVM_10002": "vhost-user 데이터 볼륨을 온라인으로 연결할 수 없습니다: 실행 중인 VM에 공유 메모리가 활성화되어 있지 않습니다. VM을 종료한 후 연결하거나, 전역 구성 generate.config.vhost.required 를 auto 또는 true 로 설정하고 VM을 재시작하십시오(해당 VM의 메모리 오버커밋이 비활성화됩니다).", "ORG_ZSTACK_NETWORK_L3_10029": "%s은(는) 클라우드 리소스 구성에 유효한 IPv6 주소가 아닙니다", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough는 호스트 환경에서 실행되는 VM에서만 사용하도록 지원됩니다.", "ORG_ZSTACK_ALIYUN_ECS_10019": "관리자 사용자만 매개변수 [onlyZstack]을 false로 설정할 수 있습니다.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json b/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json index 7a9891325cf..0d532e7b392 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-ru-RU.json @@ -2961,6 +2961,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "Не удалось получить пароль целостности из базы данных, так как %s не сгенерировал пароль целостности", "ORG_ZSTACK_VHOST_KVM_10000": "Диск vHostUser поддерживает только режим virtio. Пожалуйста, убедитесь, что на платформе образа установлены необходимые драйверы virtio.", "ORG_ZSTACK_VHOST_KVM_10001": "Диск vhost-user не поддерживает режим virtio-scsi; пожалуйста, отключите режим virtio-scsi.", + "ORG_ZSTACK_VHOST_KVM_10002": "Невозможно подключить vhost-user диск онлайн: в работающей ВМ не включена общая память. Выключите ВМ и подключите диск, либо установите глобальную настройку «generate.config.vhost.required» в «auto» или «true» и перезапустите ВМ (это отключит переподписку памяти для ВМ).", "ORG_ZSTACK_NETWORK_L3_10029": "%s не является допустимым IPv6-адресом для конфигурации облачного ресурса", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough поддерживается только на VM, работающей в хостовой среде.", "ORG_ZSTACK_ALIYUN_ECS_10019": "Только административные пользователи могут установить параметр [onlyZstack] в значение false.", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json b/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json index 3d8a70d36ad..92f456b608b 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-th-TH.json @@ -2961,6 +2961,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "การรับรหัสผ่านความสมบูรณ์จากฐานข้อมูลล้มเหลวเนื่องจาก %s ไม่ได้สร้างรหัสผ่านความสมบูรณ์", "ORG_ZSTACK_VHOST_KVM_10000": "ดิสก์ vHostUser รองรับเฉพาะโหมด virtio เท่านั้น โปรดตรวจสอบว่าแพลตฟอร์มอิมเมจมีไดรเวอร์ virtio ที่จำเป็นติดตั้งอยู่", "ORG_ZSTACK_VHOST_KVM_10001": "ดิสก์ vhost-user ไม่รองรับโหมด virtio-scsi โปรดปิดใช้งานโหมด virtio-scsi", + "ORG_ZSTACK_VHOST_KVM_10002": "ไม่สามารถแนบดิสก์ vhost-user แบบออนไลน์ได้: VM ที่กำลังทำงานไม่ได้เปิดใช้หน่วยความจำแบบแชร์ กรุณาปิด VM แล้วแนบ หรือตั้งค่าคอนฟิกส่วนกลาง generate.config.vhost.required เป็น auto หรือ true แล้วรีสตาร์ท VM (จะปิดการ overcommit หน่วยความจำของ VM นี้)", "ORG_ZSTACK_NETWORK_L3_10029": "%s ไม่ใช่ที่อยู่ IPv6 ที่ถูกต้องสำหรับการกำหนดค่าทรัพยากรคลาว์", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough รองรับการใช้งานบน VM ที่ทำงานในสภาพแวดล้อมโฮสต์เท่านั้น", "ORG_ZSTACK_ALIYUN_ECS_10019": "เฉพาะผู้ใช้ผู้ดูแลระบบเท่านั้นที่สามารถตั้งค่าพารามิเตอร์ [onlyZstack] เป็น false ได้", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json index 481cd268b83..4b7c8d05194 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-zh_CN.json @@ -448,6 +448,10 @@ "ORG_ZSTACK_STORAGE_CEPH_PRIMARY_10050": "Ceph ps[uuid\u003d%s] 根池名称未找到", "ORG_ZSTACK_STORAGE_CEPH_PRIMARY_10052": "删除卷链错误,继续删除", "ORG_ZSTACK_COMPUTE_VM_10320": "VmInstanceStartExtensionPoint[%s] 拒绝启动 vm[uuid:%s],因为 %s", + "ORG_ZSTACK_COMPUTE_VM_10331": "虚拟机网卡生命周期 setup 阶段筛选适用网卡失败:%s", + "ORG_ZSTACK_COMPUTE_VM_10332": "虚拟机网卡生命周期扩展[%s]在主机[uuid:%s]上执行 setup 失败:%s", + "ORG_ZSTACK_COMPUTE_VM_10333": "虚拟机网卡生命周期迁移前阶段筛选适用网卡失败:%s", + "ORG_ZSTACK_COMPUTE_VM_10334": "虚拟机网卡生命周期扩展[%s]执行从主机[uuid:%s]到主机[uuid:%s]的迁移前检查失败:%s", "ORG_ZSTACK_COMPUTE_HOST_10013": "网络接口[name:%s]主机[uuid:%s]未找到", "ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10008": "加密 %s[id:%s] 错误: %s", "ORG_ZSTACK_CRYPTO_DATACRYPTO_SMP_10000": "共享挂载点主存储[uuid:%s, 名称:%s]无法在附加的集群中找到任何可用主机", @@ -2963,6 +2967,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "从数据库获取完整性密码失败,因为 [%s] 未生成完整性密码", "ORG_ZSTACK_VHOST_KVM_10000": "vhostuser磁盘仅支持virtio模式,请检查镜像平台是否包含virtio驱动程序", "ORG_ZSTACK_VHOST_KVM_10001": "vhost-user磁盘不支持virtio-scsi模式,请关闭virtio-scsi模式", + "ORG_ZSTACK_VHOST_KVM_10002": "无法在线挂载vhost数据盘:该运行中云主机未启用共享内存。两种方式:1) 关机后再挂载;2) 将全局配置 generate.config.vhost.required 设为 auto 或 true 后重启该云主机(会禁用该云主机的内存超分)", "ORG_ZSTACK_NETWORK_L3_10029": "%s 不是一个有效的IPv6地址", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough 只支持在运行中的主机 VM 上使用", "ORG_ZSTACK_ALIYUN_ECS_10019": "只有管理员可以将参数 [onlyZstack] 设置为 false", @@ -4179,6 +4184,8 @@ "ORG_ZSTACK_POLICYROUTE_10010": "下一跳IP必须是ipv4格式,但发现[%s]", "ORG_ZSTACK_CORE_REST_10012": "无法在 %sms 内回显 %s", "ORG_ZSTACK_CORE_REST_10013": "物理机[uuid:%s]上的 kvmagent 于 %s 重启,丢弃发出于 %s 之前的待处理 HTTP 请求", + "ORG_ZSTACK_CORE_REST_10014": "处理 REST API 失败:%s", + "ORG_ZSTACK_CORE_REST_10015": "REST API 请求失败:%s", "ORG_ZSTACK_QUERY_10021": "字段[%s]不是库存%s中的原始类型;你无法在参数\u0027fields\u0027中指定它;有效的字段是%s", "ORG_ZSTACK_NETWORK_SERVICE_FLAT_10034": "DHCP服务器IP [%s] 已存在于L3网络 [%s] 中", "ORG_ZSTACK_QUERY_10020": "实体元类[%s]不存在字段[%s]", diff --git a/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json b/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json index 714160303db..9b95c088387 100644 --- a/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json +++ b/conf/i18n/globalErrorCodeMapping/global-error-zh_TW.json @@ -2961,6 +2961,7 @@ "ORG_ZSTACK_CRYPTO_AUTH_10019": "从數据库獲取完整性密碼失敗,因为 [%s] 未生成完整性密碼", "ORG_ZSTACK_VHOST_KVM_10000": "vhostuser磁碟仅支持virtio模式,請检查镜像平台是否包含virtio驱動程序", "ORG_ZSTACK_VHOST_KVM_10001": "vhost-user磁碟不支持virtio-scsi模式,請關閉virtio-scsi模式", + "ORG_ZSTACK_VHOST_KVM_10002": "無法在線掛載vhost資料磁碟:該執行中雲主機未啟用共享記憶體。兩種方式:1) 關機後再掛載;2) 將全域配置 generate.config.vhost.required 設為 auto 或 true 後重啟該雲主機(會停用該雲主機的記憶體超分配)", "ORG_ZSTACK_NETWORK_L3_10029": "%s 不是一個有效的IPv6地址", "ORG_ZSTACK_USBDEVICE_10005": "PassThrough 只支持在運行中的主機 VM 上使用", "ORG_ZSTACK_ALIYUN_ECS_10019": "只有管理員可以将參數 [onlyZstack] 設置为 false", diff --git a/conf/persistence.xml b/conf/persistence.xml index b66d6319ff7..52c804b55dc 100755 --- a/conf/persistence.xml +++ b/conf/persistence.xml @@ -90,6 +90,7 @@ org.zstack.header.identity.SessionVO org.zstack.header.identity.AccountVO org.zstack.header.identity.AccountResourceRefVO + org.zstack.header.resource.ResourceSourceRefVO org.zstack.header.identity.UserVO org.zstack.header.identity.PolicyVO org.zstack.header.identity.UserPolicyRefVO @@ -217,6 +218,9 @@ org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpRefVO org.zstack.header.volume.block.BlockVolumeVO org.zstack.header.host.HostHwMonitorStatusVO + org.zstack.header.volumeCache.HostCacheStoreVO + org.zstack.header.volumeCache.HostCacheStoreCapacityVO + org.zstack.header.volumeCache.VolumeCacheVO org.zstack.kvm.xmlhook.XmlHookVO org.zstack.kvm.xmlhook.XmlHookVmInstanceRefVO org.zstack.log.server.LogServerVO diff --git a/conf/serviceConfig/host.xml b/conf/serviceConfig/host.xml index bb076932f7e..b91f5c79059 100755 --- a/conf/serviceConfig/host.xml +++ b/conf/serviceConfig/host.xml @@ -61,6 +61,10 @@ org.zstack.header.host.APIGetHostPowerStatusMsg + + org.zstack.header.host.APIGetBlockDevicesMsg + + org.zstack.header.host.APICreateHostNetworkServiceTypeMsg diff --git a/conf/serviceConfig/rbac.xml b/conf/serviceConfig/rbac.xml index dd6061d80aa..db17591c436 100755 --- a/conf/serviceConfig/rbac.xml +++ b/conf/serviceConfig/rbac.xml @@ -15,14 +15,19 @@ org.zstack.header.identity.role.api.APIDeleteRoleMsg - - org.zstack.header.identity.role.api.APIQueryRoleMsg - query - - - - org.zstack.header.identity.role.api.APIChangeRoleStateMsg - + + org.zstack.header.identity.role.api.APIQueryRoleMsg + query + + + + org.zstack.header.resource.APIQueryResourceSourceRefMsg + query + + + + org.zstack.header.identity.role.api.APIChangeRoleStateMsg + org.zstack.header.identity.role.api.APIAttachPolicyToRoleMsg diff --git a/conf/springConfigXml/DatabaseFacade.xml b/conf/springConfigXml/DatabaseFacade.xml index d7afee98688..44f93eae20b 100755 --- a/conf/springConfigXml/DatabaseFacade.xml +++ b/conf/springConfigXml/DatabaseFacade.xml @@ -78,7 +78,7 @@ infinispan searchConfig/default-infinispan.xml ${Exclusive.indexUse:false} - jgroups + ${Search.backend:jgroups} searchConfig/jgroup-backend-tcp.xml \n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def attachDataVolumeToHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachDataVolumeToHostAction.class) Closure c) { def a = new org.zstack.sdk.AttachDataVolumeToHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -5714,6 +5741,33 @@ abstract class ApiHelper { } + def changeHostCacheStoreState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostCacheStoreStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeHostCacheStoreStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def changeHostNetworkInterfaceLldpMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostNetworkInterfaceLldpModeAction.class) Closure c) { def a = new org.zstack.sdk.ChangeHostNetworkInterfaceLldpModeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -9764,6 +9818,33 @@ abstract class ApiHelper { } + def createHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.CreateHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def createHostNetworkServiceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHostNetworkServiceTypeAction.class) Closure c) { def a = new org.zstack.sdk.CreateHostNetworkServiceTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -14948,6 +15029,33 @@ abstract class ApiHelper { } + def deleteHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def deleteHostNetworkServiceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostNetworkServiceTypeAction.class) Closure c) { def a = new org.zstack.sdk.DeleteHostNetworkServiceTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -18620,33 +18728,6 @@ abstract class ApiHelper { } - def attachDGpuToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachDGpuToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachDGpuToVmAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - def detachBaremetalPxeServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction.class) Closure c) { def a = new org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -19862,6 +19943,33 @@ abstract class ApiHelper { } + def disableVolumeCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DisableVolumeCacheAction.class) Closure c) { + def a = new org.zstack.sdk.DisableVolumeCacheAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def discoverExternalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DiscoverExternalPrimaryStorageAction.class) Closure c) { def a = new org.zstack.sdk.DiscoverExternalPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -20024,6 +20132,33 @@ abstract class ApiHelper { } + def enableVolumeCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EnableVolumeCacheAction.class) Closure c) { + def a = new org.zstack.sdk.EnableVolumeCacheAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def executeAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteAutoScalingRuleAction.class) Closure c) { def a = new org.zstack.sdk.ExecuteAutoScalingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -20402,6 +20537,33 @@ abstract class ApiHelper { } + def extendHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExtendHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.ExtendHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def failoverFaultToleranceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FailoverFaultToleranceVmAction.class) Closure c) { def a = new org.zstack.sdk.FailoverFaultToleranceVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -21293,6 +21455,33 @@ abstract class ApiHelper { } + def getBlockDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBlockDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.GetBlockDevicesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def getBlockPrimaryStorageMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBlockPrimaryStorageMetadataAction.class) Closure c) { def a = new org.zstack.sdk.GetBlockPrimaryStorageMetadataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -23696,6 +23885,33 @@ abstract class ApiHelper { } + def getLicenseAuthorizationInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseAuthorizationInfoAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseAuthorizationInfoAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def getLicenseCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseCapabilitiesAction.class) Closure c) { def a = new org.zstack.sdk.GetLicenseCapabilitiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -31989,6 +32205,35 @@ abstract class ApiHelper { } + def queryHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def queryHostNetworkBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkBondingAction.class) Closure c) { def a = new org.zstack.sdk.QueryHostNetworkBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -34889,6 +35134,35 @@ abstract class ApiHelper { } + def queryResourceSourceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceSourceRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryResourceSourceRefAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def queryResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceStackAction.class) Closure c) { def a = new org.zstack.sdk.QueryResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -37794,6 +38068,33 @@ abstract class ApiHelper { } + def reconnectHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def reconnectIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectIPsecConnectionAction.class) Closure c) { def a = new org.zstack.sdk.ReconnectIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -40683,33 +40984,6 @@ abstract class ApiHelper { } - def updateVmDGpu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmDGpuAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmDGpuAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - def setVmEmulatorPinning(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmEmulatorPinningAction.class) Closure c) { def a = new org.zstack.sdk.SetVmEmulatorPinningAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -42303,6 +42577,33 @@ abstract class ApiHelper { } + def syncHostCacheStoreCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncHostCacheStoreCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.SyncHostCacheStoreCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def syncHybridEipFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncHybridEipFromRemoteAction.class) Closure c) { def a = new org.zstack.sdk.SyncHybridEipFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -45516,6 +45817,33 @@ abstract class ApiHelper { } + def updateHostCacheStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostCacheStoreAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostCacheStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def updateHostIommuState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostIommuStateAction.class) Closure c) { def a = new org.zstack.sdk.UpdateHostIommuStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -48108,6 +48436,33 @@ abstract class ApiHelper { } + def updateVmDGpu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmDGpuAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmDGpuAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def updateVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmInstanceAction.class) Closure c) { def a = new org.zstack.sdk.UpdateVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -50143,6 +50498,33 @@ abstract class ApiHelper { } + def configureIAM2ScimReceiver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ConfigureIAM2ScimReceiverAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ConfigureIAM2ScimReceiverAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def createIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction.class) Closure c) { def a = new org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -55710,6 +56092,35 @@ abstract class ApiHelper { } + def queryAlarmResourceState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.QueryAlarmResourceStateAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.alarm.QueryAlarmResourceStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def queryAlertDataAck(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.QueryAlertDataAckAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.alarm.QueryAlertDataAckAction() a.sessionId = Test.currentEnvSpec?.session?.uuid diff --git a/utils/src/main/java/org/zstack/utils/TagUtils.java b/utils/src/main/java/org/zstack/utils/TagUtils.java index 823a7af6dc2..8e27ab15d87 100755 --- a/utils/src/main/java/org/zstack/utils/TagUtils.java +++ b/utils/src/main/java/org/zstack/utils/TagUtils.java @@ -8,14 +8,20 @@ /** */ public class TagUtils { - public static Map parse(String fmt, String tag) { - List origins = new ArrayList(); - Collections.addAll(origins, tag.split("::")); + private static final String TAG_DELIMITER = "::"; + private static final char TOKEN_START = '{'; + private static final char TOKEN_END = '}'; + public static Map parse(String fmt, String tag) { List t = new ArrayList(); - Collections.addAll(t, fmt.split("::")); + t.addAll(splitTagFields(fmt)); + List origins = splitTagFieldsByFormat(t, tag); Map ret = new HashMap(); + if (origins == null) { + return ret; + } + for (int i=0;i origins = new ArrayList(); - Collections.addAll(origins, tag.split("::")); - List t = new ArrayList(); - Collections.addAll(t, fmt.split("::")); + t.addAll(splitTagFields(fmt)); - if (fmt.indexOf("::") == -1) { + if (fmt.indexOf(TAG_DELIMITER) == -1 && !isTokenField(fmt)) { return fmt.equals(tag); } - if (origins.size() != t.size()) { + List origins = splitTagFieldsByFormat(t, tag); + if (origins == null || origins.size() != t.size()) { return false; } @@ -66,6 +70,90 @@ public static boolean isMatch(String fmt, String tag) { return true; } + private static List splitTagFieldsByFormat(List fmtFields, String tag) { + List fields = new ArrayList<>(); + int offset = 0; + + for (int i = 0; i < fmtFields.size(); i++) { + String fmtField = fmtFields.get(i); + boolean lastField = i == fmtFields.size() - 1; + if (isTokenField(fmtField)) { + if (lastField) { + fields.add(tag.substring(offset)); + offset = tag.length(); + continue; + } + + int end = findTokenEnd(fmtFields, tag, offset, i + 1); + if (end < 0) { + return null; + } + fields.add(tag.substring(offset, end)); + offset = end + TAG_DELIMITER.length(); + continue; + } + + if (!tag.startsWith(fmtField, offset)) { + return null; + } + + fields.add(fmtField); + offset += fmtField.length(); + if (!lastField) { + if (!tag.startsWith(TAG_DELIMITER, offset)) { + return null; + } + offset += TAG_DELIMITER.length(); + } + } + + return offset == tag.length() ? fields : null; + } + + private static boolean isTokenField(String field) { + return field.startsWith(String.valueOf(TOKEN_START)) && field.endsWith(String.valueOf(TOKEN_END)); + } + + private static List splitTagFields(String tag) { + List fields = new ArrayList<>(); + StringBuilder field = new StringBuilder(); + int braceDepth = 0; + + for (int i = 0; i < tag.length(); i++) { + char current = tag.charAt(i); + if (current == TOKEN_START) { + braceDepth++; + } else if (current == TOKEN_END && braceDepth > 0) { + braceDepth--; + } + + if (braceDepth == 0 && tag.startsWith(TAG_DELIMITER, i)) { + fields.add(field.toString()); + field.setLength(0); + i += TAG_DELIMITER.length() - 1; + continue; + } + + field.append(current); + } + + fields.add(field.toString()); + while (!fields.isEmpty() && fields.get(fields.size() - 1).isEmpty()) { + fields.remove(fields.size() - 1); + } + + return fields; + } + + private static int findTokenEnd(List fmtFields, String tag, int offset, int nextFieldIndex) { + String nextField = fmtFields.get(nextFieldIndex); + if (isTokenField(nextField)) { + return tag.indexOf(TAG_DELIMITER, offset); + } + + return tag.indexOf(TAG_DELIMITER + nextField, offset); + } + public static Map parseIfMatch(String fmt, String tag) { if (!isMatch(fmt, tag)) { return null; diff --git a/utils/src/main/java/org/zstack/utils/URLBuilder.java b/utils/src/main/java/org/zstack/utils/URLBuilder.java index cc2ed0ddb4c..047323db74c 100755 --- a/utils/src/main/java/org/zstack/utils/URLBuilder.java +++ b/utils/src/main/java/org/zstack/utils/URLBuilder.java @@ -2,11 +2,14 @@ import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; +import org.zstack.utils.network.IPv6NetworkUtils; public class URLBuilder { + private static final String BASE_URL_FORMAT = "%s://%s:%s"; + public static String buildUrl(String scheme, String host, int port, String...paths) { - UriComponentsBuilder builder = UriComponentsBuilder.newInstance(); - builder.scheme(scheme).host(host).port(port); + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString( + String.format(BASE_URL_FORMAT, scheme, IPv6NetworkUtils.formatHostForUrl(host), port)); for (String p : paths) { builder.path(p); } diff --git a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java index 27c12405e70..1c98f41a281 100644 --- a/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java +++ b/utils/src/main/java/org/zstack/utils/clouderrorcode/CloudOperationsErrorCode.java @@ -254,6 +254,16 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10083 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10083"; + public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10084 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10084"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10085 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10085"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10086 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10086"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10087 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10087"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10088 = "ORG_ZSTACK_STORAGE_BACKUP_IMAGESTORE_10088"; + public static final String ORG_ZSTACK_MTTYDEVICE_KVMMTTYDEVICEBACKEND_10000 = "ORG_ZSTACK_MTTYDEVICE_KVMMTTYDEVICEBACKEND_10000"; public static final String ORG_ZSTACK_MTTYDEVICE_KVMMTTYDEVICEBACKEND_10001 = "ORG_ZSTACK_MTTYDEVICE_KVMMTTYDEVICEBACKEND_10001"; @@ -672,6 +682,12 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10034 = "ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10034"; + public static final String ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10035 = "ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10035"; + + public static final String ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10036 = "ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10036"; + + public static final String ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10037 = "ORG_ZSTACK_ALIYUN_EBS_STORAGE_PRIMARY_10037"; + public static final String ORG_ZSTACK_ALIYUN_CORE_IDENTITYZONE_10000 = "ORG_ZSTACK_ALIYUN_CORE_IDENTITYZONE_10000"; public static final String ORG_ZSTACK_TEST_INTEGRATION_KVM_VM_10000 = "ORG_ZSTACK_TEST_INTEGRATION_KVM_VM_10000"; @@ -978,6 +994,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_NETWORK_L3_10081 = "ORG_ZSTACK_NETWORK_L3_10081"; + public static final String ORG_ZSTACK_NETWORK_L3_10082 = "ORG_ZSTACK_NETWORK_L3_10082"; + public static final String ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_SUPPLIER_EMAY_10000 = "ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_SUPPLIER_EMAY_10000"; public static final String ORG_ZSTACK_CORE_VALIDATION_10000 = "ORG_ZSTACK_CORE_VALIDATION_10000"; @@ -1054,6 +1072,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_CONSOLE_10013 = "ORG_ZSTACK_CONSOLE_10013"; + public static final String ORG_ZSTACK_CONSOLE_10014 = "ORG_ZSTACK_CONSOLE_10014"; + + public static final String ORG_ZSTACK_CONSOLE_10015 = "ORG_ZSTACK_CONSOLE_10015"; + public static final String ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORK_10000 = "ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORK_10000"; public static final String ORG_ZSTACK_NETWORK_SERVICE_HEADER_NFVINSTGROUP_10000 = "ORG_ZSTACK_NETWORK_SERVICE_HEADER_NFVINSTGROUP_10000"; @@ -2836,6 +2858,14 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_COMPUTE_ZONE_10003 = "ORG_ZSTACK_COMPUTE_ZONE_10003"; + public static final String ORG_ZSTACK_COMPUTE_ZONE_10004 = "ORG_ZSTACK_COMPUTE_ZONE_10004"; + + public static final String ORG_ZSTACK_COMPUTE_ZONE_10005 = "ORG_ZSTACK_COMPUTE_ZONE_10005"; + + public static final String ORG_ZSTACK_COMPUTE_ZONE_10006 = "ORG_ZSTACK_COMPUTE_ZONE_10006"; + + public static final String ORG_ZSTACK_COMPUTE_ZONE_10007 = "ORG_ZSTACK_COMPUTE_ZONE_10007"; + public static final String ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10000 = "ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10000"; public static final String ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10001 = "ORG_ZSTACK_CRYPTO_DATACRYPTO_INTEGRITY_10001"; @@ -3388,6 +3418,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_DEVICE_10048 = "ORG_ZSTACK_STORAGE_DEVICE_10048"; + public static final String ORG_ZSTACK_STORAGE_DEVICE_10049 = "ORG_ZSTACK_STORAGE_DEVICE_10049"; + public static final String ORG_ZSTACK_CORE_GC_10000 = "ORG_ZSTACK_CORE_GC_10000"; public static final String ORG_ZSTACK_CORE_GC_10001 = "ORG_ZSTACK_CORE_GC_10001"; @@ -3582,6 +3614,18 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_PRIMARY_10053 = "ORG_ZSTACK_STORAGE_PRIMARY_10053"; + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10055 = "ORG_ZSTACK_STORAGE_PRIMARY_10055"; + + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10056 = "ORG_ZSTACK_STORAGE_PRIMARY_10056"; + + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10057 = "ORG_ZSTACK_STORAGE_PRIMARY_10057"; + + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10058 = "ORG_ZSTACK_STORAGE_PRIMARY_10058"; + + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10059 = "ORG_ZSTACK_STORAGE_PRIMARY_10059"; + + public static final String ORG_ZSTACK_STORAGE_PRIMARY_10060 = "ORG_ZSTACK_STORAGE_PRIMARY_10060"; + public static final String ORG_ZSTACK_CORE_ENCRYPT_10000 = "ORG_ZSTACK_CORE_ENCRYPT_10000"; public static final String ORG_ZSTACK_TEST_INTEGRATION_PREMIUM_NETWORKSERVICE_SLB_10000 = "ORG_ZSTACK_TEST_INTEGRATION_PREMIUM_NETWORKSERVICE_SLB_10000"; @@ -4878,6 +4922,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_V2V_VMWARE_10017 = "ORG_ZSTACK_V2V_VMWARE_10017"; + public static final String ORG_ZSTACK_V2V_VMWARE_10018 = "ORG_ZSTACK_V2V_VMWARE_10018"; + public static final String ORG_ZSTACK_LDAP_EXTERNALSEARCH_10000 = "ORG_ZSTACK_LDAP_EXTERNALSEARCH_10000"; public static final String ORG_ZSTACK_IDENTITY_10000 = "ORG_ZSTACK_IDENTITY_10000"; @@ -5544,6 +5590,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_BAREMETAL2_GATEWAY_10085 = "ORG_ZSTACK_BAREMETAL2_GATEWAY_10085"; + public static final String ORG_ZSTACK_BAREMETAL2_GATEWAY_10086 = "ORG_ZSTACK_BAREMETAL2_GATEWAY_10086"; + + public static final String ORG_ZSTACK_BAREMETAL2_GATEWAY_10087 = "ORG_ZSTACK_BAREMETAL2_GATEWAY_10087"; + public static final String ORG_ZSTACK_BAREMETAL2_DPU_10000 = "ORG_ZSTACK_BAREMETAL2_DPU_10000"; public static final String ORG_ZSTACK_BAREMETAL2_DPU_10001 = "ORG_ZSTACK_BAREMETAL2_DPU_10001"; @@ -6346,6 +6396,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_BACKUP_10133 = "ORG_ZSTACK_STORAGE_BACKUP_10133"; + public static final String ORG_ZSTACK_STORAGE_BACKUP_10134 = "ORG_ZSTACK_STORAGE_BACKUP_10134"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_10135 = "ORG_ZSTACK_STORAGE_BACKUP_10135"; + public static final String ORG_ZSTACK_STORAGE_BACKUP_CANCEL_TIMEOUT = "ORG_ZSTACK_STORAGE_BACKUP_CANCEL_TIMEOUT"; public static final String ORG_ZSTACK_COMPUTE_10000 = "ORG_ZSTACK_COMPUTE_10000"; @@ -6724,6 +6778,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_BAREMETAL_PXESERVER_10036 = "ORG_ZSTACK_BAREMETAL_PXESERVER_10036"; + public static final String ORG_ZSTACK_BAREMETAL_PXESERVER_10037 = "ORG_ZSTACK_BAREMETAL_PXESERVER_10037"; + public static final String ORG_ZSTACK_TEST_INTEGRATION_V2V_10000 = "ORG_ZSTACK_TEST_INTEGRATION_V2V_10000"; public static final String ORG_ZSTACK_TEST_INTEGRATION_V2V_10001 = "ORG_ZSTACK_TEST_INTEGRATION_V2V_10001"; @@ -7868,6 +7924,12 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10031 = "ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10031"; + public static final String ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10032 = "ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10032"; + + public static final String ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10033 = "ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10033"; + + public static final String ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10034 = "ORG_ZSTACK_NETWORK_L2_VXLAN_VXLANNETWORKPOOL_10034"; + public static final String ORG_ZSTACK_IAM2_CONTAINER_ZAKU_10000 = "ORG_ZSTACK_IAM2_CONTAINER_ZAKU_10000"; public static final String ORG_ZSTACK_IAM2_CONTAINER_ZAKU_10001 = "ORG_ZSTACK_IAM2_CONTAINER_ZAKU_10001"; @@ -8514,6 +8576,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_V2V_KVM_10012 = "ORG_ZSTACK_V2V_KVM_10012"; + public static final String ORG_ZSTACK_V2V_KVM_10013 = "ORG_ZSTACK_V2V_KVM_10013"; + public static final String ORG_ZSTACK_IPSEC_VYOS_10000 = "ORG_ZSTACK_IPSEC_VYOS_10000"; public static final String ORG_ZSTACK_IPSEC_VYOS_10001 = "ORG_ZSTACK_IPSEC_VYOS_10001"; @@ -9950,6 +10014,14 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_COMPUTE_VM_10330 = "ORG_ZSTACK_COMPUTE_VM_10330"; + public static final String ORG_ZSTACK_COMPUTE_VM_10331 = "ORG_ZSTACK_COMPUTE_VM_10331"; + + public static final String ORG_ZSTACK_COMPUTE_VM_10332 = "ORG_ZSTACK_COMPUTE_VM_10332"; + + public static final String ORG_ZSTACK_COMPUTE_VM_10333 = "ORG_ZSTACK_COMPUTE_VM_10333"; + + public static final String ORG_ZSTACK_COMPUTE_VM_10334 = "ORG_ZSTACK_COMPUTE_VM_10334"; + public static final String ORG_ZSTACK_IDENTITY_LOGIN_10000 = "ORG_ZSTACK_IDENTITY_LOGIN_10000"; public static final String ORG_ZSTACK_STORAGE_VOLUME_BLOCK_EXPON_10000 = "ORG_ZSTACK_STORAGE_VOLUME_BLOCK_EXPON_10000"; @@ -10619,6 +10691,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_CORE_REST_10013 = "ORG_ZSTACK_CORE_REST_10013"; + public static final String ORG_ZSTACK_CORE_REST_10014 = "ORG_ZSTACK_CORE_REST_10014"; + + public static final String ORG_ZSTACK_CORE_REST_10015 = "ORG_ZSTACK_CORE_REST_10015"; + public static final String ORG_ZSTACK_LICENSE_10000 = "ORG_ZSTACK_LICENSE_10000"; public static final String ORG_ZSTACK_LICENSE_10001 = "ORG_ZSTACK_LICENSE_10001"; @@ -11211,6 +11287,14 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_COMPUTE_HOST_10127 = "ORG_ZSTACK_COMPUTE_HOST_10127"; + public static final String ORG_ZSTACK_COMPUTE_HOST_10128 = "ORG_ZSTACK_COMPUTE_HOST_10128"; + + public static final String ORG_ZSTACK_COMPUTE_HOST_10129 = "ORG_ZSTACK_COMPUTE_HOST_10129"; + + public static final String ORG_ZSTACK_COMPUTE_HOST_10130 = "ORG_ZSTACK_COMPUTE_HOST_10130"; + + public static final String ORG_ZSTACK_COMPUTE_HOST_10131 = "ORG_ZSTACK_COMPUTE_HOST_10131"; + public static final String ORG_ZSTACK_MONITORING_TRIGGER_EXPRESSION_10000 = "ORG_ZSTACK_MONITORING_TRIGGER_EXPRESSION_10000"; public static final String ORG_ZSTACK_MONITORING_TRIGGER_EXPRESSION_10001 = "ORG_ZSTACK_MONITORING_TRIGGER_EXPRESSION_10001"; @@ -11723,6 +11807,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_PCIDEVICE_10077 = "ORG_ZSTACK_PCIDEVICE_10077"; + public static final String ORG_ZSTACK_PCIDEVICE_10078 = "ORG_ZSTACK_PCIDEVICE_10078"; + public static final String ORG_ZSTACK_CAS_DRIVER_DONGHAI_10000 = "ORG_ZSTACK_CAS_DRIVER_DONGHAI_10000"; public static final String ORG_ZSTACK_CAS_DRIVER_DONGHAI_10001 = "ORG_ZSTACK_CAS_DRIVER_DONGHAI_10001"; @@ -12199,6 +12285,8 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_VHOST_KVM_10001 = "ORG_ZSTACK_VHOST_KVM_10001"; + public static final String ORG_ZSTACK_VHOST_KVM_10002 = "ORG_ZSTACK_VHOST_KVM_10002"; + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10000 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10000"; public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10001 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10001"; @@ -12249,6 +12337,16 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10024 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10024"; + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10025 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10025"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10026 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10026"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10027 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10027"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10028 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10028"; + + public static final String ORG_ZSTACK_STORAGE_BACKUP_SFTP_10029 = "ORG_ZSTACK_STORAGE_BACKUP_SFTP_10029"; + public static final String ORG_ZSTACK_TEST_CORE_ERRORCODE_10000 = "ORG_ZSTACK_TEST_CORE_ERRORCODE_10000"; public static final String ORG_ZSTACK_TEST_CORE_ERRORCODE_10001 = "ORG_ZSTACK_TEST_CORE_ERRORCODE_10001"; @@ -13265,6 +13363,12 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_VPC_HA_10020 = "ORG_ZSTACK_VPC_HA_10020"; + public static final String ORG_ZSTACK_VPC_HA_10021 = "ORG_ZSTACK_VPC_HA_10021"; + + public static final String ORG_ZSTACK_VPC_HA_10022 = "ORG_ZSTACK_VPC_HA_10022"; + + public static final String ORG_ZSTACK_VPC_HA_10023 = "ORG_ZSTACK_VPC_HA_10023"; + public static final String ORG_ZSTACK_SSO_CAS_FILTER_10000 = "ORG_ZSTACK_SSO_CAS_FILTER_10000"; public static final String ORG_ZSTACK_SSO_CAS_FILTER_10001 = "ORG_ZSTACK_SSO_CAS_FILTER_10001"; @@ -14137,6 +14241,28 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_STORAGE_CEPH_10025 = "ORG_ZSTACK_STORAGE_CEPH_10025"; + public static final String ORG_ZSTACK_STORAGE_CEPH_10026 = "ORG_ZSTACK_STORAGE_CEPH_10026"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10027 = "ORG_ZSTACK_STORAGE_CEPH_10027"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10028 = "ORG_ZSTACK_STORAGE_CEPH_10028"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10029 = "ORG_ZSTACK_STORAGE_CEPH_10029"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10030 = "ORG_ZSTACK_STORAGE_CEPH_10030"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10031 = "ORG_ZSTACK_STORAGE_CEPH_10031"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10032 = "ORG_ZSTACK_STORAGE_CEPH_10032"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10033 = "ORG_ZSTACK_STORAGE_CEPH_10033"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10034 = "ORG_ZSTACK_STORAGE_CEPH_10034"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10035 = "ORG_ZSTACK_STORAGE_CEPH_10035"; + + public static final String ORG_ZSTACK_STORAGE_CEPH_10036 = "ORG_ZSTACK_STORAGE_CEPH_10036"; + public static final String ORG_ZSTACK_HYBRID_DATACENTER_10000 = "ORG_ZSTACK_HYBRID_DATACENTER_10000"; public static final String ORG_ZSTACK_HYBRID_DATACENTER_10001 = "ORG_ZSTACK_HYBRID_DATACENTER_10001"; @@ -15312,6 +15438,10 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_V2V_10038 = "ORG_ZSTACK_V2V_10038"; + public static final String ORG_ZSTACK_V2V_10039 = "ORG_ZSTACK_V2V_10039"; + + public static final String ORG_ZSTACK_V2V_10040 = "ORG_ZSTACK_V2V_10040"; + public static final String ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_10000 = "ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_10000"; public static final String ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_10001 = "ORG_ZSTACK_SNS_PLATFORM_UNIVERSALSMS_10001"; @@ -16231,4 +16361,76 @@ public class CloudOperationsErrorCode { public static final String ORG_ZSTACK_DGPU_10012 = "ORG_ZSTACK_DGPU_10012"; public static final String ORG_ZSTACK_DGPU_10013 = "ORG_ZSTACK_DGPU_10013"; + + public static final String ORG_ZSTACK_DGPU_10014 = "ORG_ZSTACK_DGPU_10014"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10001 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10001"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10002 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10002"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10003 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10003"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10004 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10004"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10005 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10005"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10006 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10006"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10007 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10007"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10008 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10008"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10009 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10009"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10010 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10010"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10011 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10011"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10012 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10012"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10013 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10013"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10014 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10014"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10015 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10015"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10016 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10016"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10017 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10017"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10018 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10018"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10019 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10019"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10020 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10020"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10021 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10021"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10022 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10022"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10023 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10023"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10024 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10024"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10025 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10025"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10026 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10026"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10027 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10027"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10028 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10028"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10029 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10029"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10030 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10030"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10031 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10031"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10032 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10032"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10033 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10033"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10034 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10034"; + + public static final String ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10035 = "ORG_ZSTACK_STORAGE_LOCALVOLUMECACHE_10035"; } diff --git a/utils/src/main/java/org/zstack/utils/network/IPv6Constants.java b/utils/src/main/java/org/zstack/utils/network/IPv6Constants.java index 61c1e637906..31ae048bbff 100644 --- a/utils/src/main/java/org/zstack/utils/network/IPv6Constants.java +++ b/utils/src/main/java/org/zstack/utils/network/IPv6Constants.java @@ -11,6 +11,7 @@ public class IPv6Constants { public static final String SLAAC = "SLAAC"; public static final String Stateless_DHCP = "Stateless-DHCP"; public static final String Stateful_DHCP = "Stateful-DHCP"; + public static final String IPV6_ANY_ADDRESS = "::"; public static final int IPV6_STATELESS_PREFIX_LEN = 64; diff --git a/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java b/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java index 50bbe6f195b..355e43d3fe6 100644 --- a/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java +++ b/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java @@ -8,11 +8,18 @@ import org.zstack.utils.logging.CLogger; import java.math.BigInteger; +import java.net.Inet6Address; +import java.net.InetAddress; import java.util.Arrays; import java.util.List; public class IPv6NetworkUtils { private final static CLogger logger = Utils.getLogger(IPv6NetworkUtils.class); + private static final String URL_IPV6_HOST_FORMAT = "[%s]"; + private static final String HTTP_URL_FORMAT = "http://%s:%s"; + private static final String HOST_PORT_FORMAT = "%s:%s"; + private static final String IPV6_BRACKET_PREFIX = "["; + private static final String IPV6_BRACKET_SUFFIX = "]"; // IPv4 地址正则表达式 private static String ipv4Regex = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; @@ -134,6 +141,9 @@ public static String getIPv6AddresFromMac(String networkCidr, String mac) { } public static boolean isIpv6Address(String ip) { + if (ip == null) { + return false; + } try { IPv6Address.fromString(ip); return true; @@ -143,6 +153,9 @@ public static boolean isIpv6Address(String ip) { } public static boolean isIpv6UnicastAddress(String ip) { + if (ip == null) { + return false; + } try { IPv6Address address = IPv6Address.fromString(ip); if (address.isMulticast() || address.isLinkLocal() || address.isSiteLocal()) { @@ -500,4 +513,65 @@ public static String getIpByIpVersion(String ipVersion, List ipList) { public static boolean isFullCidr(String cidr) { return cidr.equals("::/0"); } + + public static String normalizeIpv6(String ip) { + return getIpv6AddressCanonicalString(ip); + } + + public static String formatHostForUrl(String host) { + if (host == null) { + return null; + } + + if (host.startsWith(IPV6_BRACKET_PREFIX) && host.endsWith(IPV6_BRACKET_SUFFIX)) { + return host; + } + + return isIpv6Address(host) ? String.format(URL_IPV6_HOST_FORMAT, host) : host; + } + + public static String stripHostUrlBrackets(String host) { + if (host == null) { + return null; + } + + if (host.startsWith(IPV6_BRACKET_PREFIX) && host.endsWith(IPV6_BRACKET_SUFFIX)) { + return host.substring(IPV6_BRACKET_PREFIX.length(), host.length() - IPV6_BRACKET_SUFFIX.length()); + } + + return host; + } + + public static String buildHttpUrl(String host, int port) { + return String.format(HTTP_URL_FORMAT, formatHostForUrl(host), port); + } + + public static String formatHostPort(String host, int port) { + return String.format(HOST_PORT_FORMAT, formatHostForUrl(host), port); + } + + public static boolean isValidManagementEndpoint(String endpoint) { + if (NetworkUtils.isIpv4Address(endpoint) || NetworkUtils.isHostname(endpoint)) { + return true; + } + + return isValidManagementIpv6Address(endpoint); + } + + public static boolean isValidManagementIpv6Address(String endpoint) { + if (!isIpv6Address(endpoint)) { + return false; + } + + try { + InetAddress address = InetAddress.getByName(endpoint); + return address instanceof Inet6Address && + !address.isLinkLocalAddress() && + !address.isLoopbackAddress() && + !address.isAnyLocalAddress() && + !address.isMulticastAddress(); + } catch (Exception e) { + return false; + } + } } diff --git a/utils/src/main/java/org/zstack/utils/network/ManagementNetworkIpVersionUtils.java b/utils/src/main/java/org/zstack/utils/network/ManagementNetworkIpVersionUtils.java new file mode 100644 index 00000000000..f458dfb2bad --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/network/ManagementNetworkIpVersionUtils.java @@ -0,0 +1,105 @@ +package org.zstack.utils.network; + +import org.apache.commons.lang.StringUtils; + +public class ManagementNetworkIpVersionUtils { + public static final String IPV4 = "ipv4"; + public static final String IPV6 = "ipv6"; + + private static final String IPV6_HOST_PREFIX = "["; + private static final String IPV6_HOST_SUFFIX = "]"; + private static final String URI_SCHEME_SEPARATOR = "://"; + private static final String NFS_URL_SEPARATOR = ":/"; + private static final String PORT_SEPARATOR = ":"; + private static final String PATH_SEPARATOR = "/"; + private static final String USER_INFO_SEPARATOR = "@"; + private static final String IPV6_SCOPE_SEPARATOR = "%"; + + public static boolean isValidIpVersion(String ipVersion) { + return normalizeIpVersion(ipVersion) != null; + } + + public static String normalizeIpVersion(String ipVersion) { + if (StringUtils.isBlank(ipVersion)) { + return null; + } + + String normalizedIpVersion = ipVersion.trim().toLowerCase(); + if (IPV4.equals(normalizedIpVersion) || IPV6.equals(normalizedIpVersion)) { + return normalizedIpVersion; + } + + return null; + } + + public static String getEndpointIpVersion(String endpoint) { + String host = extractEndpointHost(endpoint); + if (NetworkUtils.isIpv4Address(host)) { + return IPV4; + } + + if (IPv6NetworkUtils.isIpv6Address(host)) { + return IPV6; + } + + return null; + } + + public static boolean isIpv6LinkLocalEndpoint(String endpoint) { + String host = extractEndpointHost(endpoint); + if (StringUtils.isBlank(host) || !host.contains(PORT_SEPARATOR)) { + return false; + } + + int scopeIndex = host.indexOf(IPV6_SCOPE_SEPARATOR); + String address = scopeIndex >= 0 ? host.substring(0, scopeIndex) : host; + return IPv6NetworkUtils.isLinkLocalAddress(address); + } + + public static String extractEndpointHost(String endpoint) { + if (StringUtils.isBlank(endpoint)) { + return null; + } + + String value = endpoint.trim(); + int schemeIndex = value.indexOf(URI_SCHEME_SEPARATOR); + if (schemeIndex >= 0) { + value = value.substring(schemeIndex + URI_SCHEME_SEPARATOR.length()); + } + + if (value.contains(USER_INFO_SEPARATOR)) { + value = value.substring(value.lastIndexOf(USER_INFO_SEPARATOR) + USER_INFO_SEPARATOR.length()); + } + + if (value.startsWith(IPV6_HOST_PREFIX)) { + return extractBracketIpv6Host(value); + } + + String hostBeforePath = value; + int pathIndex = hostBeforePath.indexOf(PATH_SEPARATOR); + if (pathIndex >= 0) { + hostBeforePath = hostBeforePath.substring(0, pathIndex); + } + + if (IPv6NetworkUtils.isIpv6Address(hostBeforePath)) { + return hostBeforePath; + } + + int nfsIndex = value.indexOf(NFS_URL_SEPARATOR); + if (nfsIndex >= 0) { + return value.substring(0, nfsIndex); + } + + int portIndex = hostBeforePath.indexOf(PORT_SEPARATOR); + if (portIndex >= 0 && hostBeforePath.indexOf(PORT_SEPARATOR, portIndex + PORT_SEPARATOR.length()) < 0) { + return hostBeforePath.substring(0, portIndex); + } + + return hostBeforePath; + } + + private static String extractBracketIpv6Host(String value) { + int end = value.indexOf(IPV6_HOST_SUFFIX); + return end > 0 ? value.substring(IPV6_HOST_PREFIX.length(), end) : value; + } +} diff --git a/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java b/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java index 3a7859fec8d..4cb6be81196 100755 --- a/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java +++ b/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java @@ -558,6 +558,23 @@ public static boolean isIpv4InCidr(String ipv4, String cidr) { return isIpv4InRange(ipv4, info.getLowAddress(), info.getHighAddress()); } + public static boolean isIpInCidr(String ip, String cidr) { + DebugUtils.Assert(isCidr(cidr), String.format("%s is not a cidr", cidr)); + validateIp(ip); + + if (isIpv4Address(ip)) { + if (!isCidr(cidr, IPv6Constants.IPv4)) { + return false; + } + return isIpv4InCidr(ip, cidr); + } + + if (!isCidr(cidr, IPv6Constants.IPv6)) { + return false; + } + return IPv6NetworkUtils.isIpv6InCidrRange(ip, cidr); + } + public static List filterIpv4sInCidr(List ipv4s, String cidr){ DebugUtils.Assert(isCidr(cidr), String.format("%s is not a cidr", cidr)); SubnetUtils.SubnetInfo info = getSubnetInfo(new SubnetUtils(cidr)); @@ -572,6 +589,19 @@ public static List filterIpv4sInCidr(List ipv4s, String cidr){ return results; } + public static List filterIpsInCidr(List ips, String cidr){ + DebugUtils.Assert(isCidr(cidr), String.format("%s is not a cidr", cidr)); + List results = new ArrayList<>(); + + for (String ip : ips) { + validateIp(ip); + if (isIpInCidr(ip, cidr)) { + results.add(ip); + } + } + return results; + } + public static boolean isIpRoutedByDefaultGateway(String ip) { ShellResult res = ShellUtils.runAndReturn(String.format("ip route get %s | grep -q \"via $(ip route | awk '/default/ {print $3}')\"", ip)); return res.isReturnCode(0); @@ -588,6 +618,10 @@ public static boolean isSubCidr(String cidr, String subCidr) { public static String getNetworkAddressFromCidr(String cidr) { DebugUtils.Assert(isCidr(cidr), String.format("%s is not a cidr", cidr)); + if (isIpv6Address(cidr.split("\\/")[0])) { + return IPv6NetworkUtils.getFormalCidrOfNetworkCidr(cidr); + } + SubnetUtils n = new SubnetUtils(cidr); return String.format("%s/%s", n.getInfo().getNetworkAddress(), cidr.split("\\/")[1]); } @@ -607,9 +641,8 @@ public static List getIpRangeFromIps(List ips){ } public static String fmtCidr(final String origin) { - // format "*.*.1.1/16" to "*.*.0.0/16" DebugUtils.Assert(isCidr(origin), String.format("%s is not a cidr", origin)); - return new SubnetUtils(origin).getInfo().getNetworkAddress() + "/" + origin.split("/")[1]; + return getNetworkAddressFromCidr(origin); } public static List getCidrsFromIpRange(String startIp, String endIp) { @@ -972,4 +1005,3 @@ public static int compareIpv4Address(String ip1, String ip2) { return diff > 0 ? 1 : diff == 0 ? 0 : -1; } } - diff --git a/utils/src/main/java/org/zstack/utils/ssh/Ssh.java b/utils/src/main/java/org/zstack/utils/ssh/Ssh.java index 69de299e258..3f61ae0b2f8 100755 --- a/utils/src/main/java/org/zstack/utils/ssh/Ssh.java +++ b/utils/src/main/java/org/zstack/utils/ssh/Ssh.java @@ -345,10 +345,11 @@ public SshResult run() { @Override public String getCommand() { + String target = SshShell.formatScpTarget(username, hostname); if (download) { - return String.format("scp -P %d %s@%s:%s %s", port, username, hostname, src, dst); + return String.format("scp -P %d %s:%s %s", port, target, src, dst); } else { - return String.format("scp -P %d %s %s@%s:%s", port, src, username, hostname, dst); + return String.format("scp -P %d %s %s:%s", port, src, target, dst); } } diff --git a/utils/src/main/java/org/zstack/utils/ssh/SshShell.java b/utils/src/main/java/org/zstack/utils/ssh/SshShell.java index 67299048bd2..46909b7681f 100755 --- a/utils/src/main/java/org/zstack/utils/ssh/SshShell.java +++ b/utils/src/main/java/org/zstack/utils/ssh/SshShell.java @@ -6,6 +6,7 @@ import org.zstack.utils.ShellUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.path.PathUtil; import java.io.File; @@ -22,6 +23,7 @@ */ public class SshShell { private static final CLogger logger = Utils.getLogger(SshShell.class); + private static final String SSH_TARGET_FORMAT = "%s@%s"; private String hostname; private String username; @@ -44,6 +46,14 @@ private void checkParams() { DebugUtils.Assert(password != null || privateKey != null, "password and privateKey must have at least one set"); } + public static String formatSshTarget(String username, String hostname) { + return String.format(SSH_TARGET_FORMAT, username, IPv6NetworkUtils.stripHostUrlBrackets(hostname)); + } + + public static String formatScpTarget(String username, String hostname) { + return String.format(SSH_TARGET_FORMAT, username, IPv6NetworkUtils.formatHostForUrl(hostname)); + } + public SshResult runCommand(String cmd) { return runCommand(cmd, false); } @@ -62,13 +72,13 @@ private SshResult runCommand(String cmd, boolean allocatePseudoTty) { if (privateKey != null) { tempPasswordFile = File.createTempFile("zstack", "tmp"); writeSecretFile(tempPasswordFile, privateKey); - ssh = String.format("ssh -q %s-i %s -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no %s -p %s %s@%s '%s'", - pseudoTtyOption, tempPasswordFile.getAbsolutePath(), sshTimeoutOptions(), port, username, hostname, cmd); + ssh = String.format("ssh -q %s-i %s -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no %s -p %s %s '%s'", + pseudoTtyOption, tempPasswordFile.getAbsolutePath(), sshTimeoutOptions(), port, formatSshTarget(username, hostname), cmd); } else { tempPasswordFile = File.createTempFile("zstack", "tmp"); writeSecretFile(tempPasswordFile, password); - ssh = String.format("sshpass -f%s ssh -q %s-o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no %s -p %s %s@%s '%s'", - tempPasswordFile.getAbsolutePath(), pseudoTtyOption, sshTimeoutOptions(), port, username, hostname, cmd); + ssh = String.format("sshpass -f%s ssh -q %s-o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no %s -p %s %s '%s'", + tempPasswordFile.getAbsolutePath(), pseudoTtyOption, sshTimeoutOptions(), port, formatSshTarget(username, hostname), cmd); } if (logger.isTraceEnabled()) { @@ -91,7 +101,7 @@ private SshResult runCommand(String cmd, boolean allocatePseudoTty) { } catch (Exception e) { throw new RuntimeException(e); } finally { - if (tempPasswordFile != null && tempPasswordFile.delete()) { + if (tempPasswordFile != null && tempPasswordFile.exists() && !tempPasswordFile.delete()) { logger.warn(String.format("failed to delete file[%s]", tempPasswordFile)); } } @@ -106,32 +116,32 @@ public SshResult runScript(String script) { tempPasswordFile = File.createTempFile("zstack", "tmp"); writeSecretFile(tempPasswordFile, privateKey); ssh = ln( - "ssh -q -i {0} -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no {5} -p {1} -T {2}@{3} << 'EOF'", + "ssh -q -i {0} -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no {4} -p {1} -T {2} << 'EOF'", "s=`mktemp`", "cat << 'EOT' > $s", - "{4}", + "{3}", "EOT", "bash $s", "ret=$?", "rm -f $s", "exit $ret", "EOF" - ).format(tempPasswordFile.getAbsolutePath(), port, username, hostname, script, sshTimeoutOptions()); + ).format(tempPasswordFile.getAbsolutePath(), port, formatSshTarget(username, hostname), script, sshTimeoutOptions()); } else { tempPasswordFile = File.createTempFile("zstack", "tmp"); writeSecretFile(tempPasswordFile, password); ssh = ln( - "sshpass -f{0} ssh -q -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no {5} -p {1} -T {2}@{3} << 'EOF'", + "sshpass -f{0} ssh -q -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no {4} -p {1} -T {2} << 'EOF'", "s=`mktemp`", "cat << 'EOT' > $s", - "{4}", + "{3}", "EOT", "bash $s", "ret=$?", "rm -f $s", "exit $ret", "EOF" - ).format(tempPasswordFile.getAbsolutePath(), port, username, hostname, script, sshTimeoutOptions()); + ).format(tempPasswordFile.getAbsolutePath(), port, formatSshTarget(username, hostname), script, sshTimeoutOptions()); } if (logger.isTraceEnabled()) { @@ -153,7 +163,7 @@ public SshResult runScript(String script) { } catch (Exception e) { throw new RuntimeException(e); } finally { - if (tempPasswordFile != null && tempPasswordFile.delete()) { + if (tempPasswordFile != null && tempPasswordFile.exists() && !tempPasswordFile.delete()) { logger.warn(String.format("failed to delete file[%s]", tempPasswordFile)); } } @@ -226,7 +236,6 @@ public Boolean getWithSudo() { public void setWithSudo(Boolean withSudo) { this.withSudo = withSudo; } - public int getConnectTimeoutSeconds() { return connectTimeoutSeconds; } diff --git a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java index 5e9d4b9a4dc..c14290d71bc 100644 --- a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java +++ b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java @@ -39,7 +39,7 @@ public static ZSha2Info getInfo(boolean checkZSha2Status) { ZSha2Info info = JSONObjectUtil.toObject(result.getStdout(), ZSha2Info.class); info.setMaster(ShellUtils.runAndReturn(String.format( - "ip addr show %s | grep -q '[^0-9]%s[^0-9]'", info.getNic(), info.getDbvip())).isReturnCode(0)); + "ip addr show %s | grep -q ' %s/'", info.getNic(), info.getDbvip())).isReturnCode(0)); return info; }