> affinityGroupNodeTypeMap);
void cleanupForAccount(Account account);
}
diff --git a/api/src/main/java/com/cloud/network/Network.java b/api/src/main/java/com/cloud/network/Network.java
index 0846306f70f9..2f0bcdd5ef9a 100644
--- a/api/src/main/java/com/cloud/network/Network.java
+++ b/api/src/main/java/com/cloud/network/Network.java
@@ -116,6 +116,7 @@ class Service {
public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols);
public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet,
Capability.NoVlan, Capability.PublicAccess);
+ public static final Service CustomAction = new Service("CustomAction");
private final String name;
private final Capability[] caps;
@@ -207,6 +208,7 @@ public static class Provider {
public static final Provider Nsx = new Provider("Nsx", false);
public static final Provider Netris = new Provider("Netris", false);
+ public static final Provider NetworkExtension = new Provider("NetworkExtension", false, true);
private final String name;
private final boolean isExternal;
@@ -250,11 +252,47 @@ public static Provider getProvider(String providerName) {
return null;
}
+ /** Private constructor for transient (non-registered) providers. */
+ private Provider(String name) {
+ this.name = name;
+ this.isExternal = false;
+ this.needCleanupOnShutdown = true;
+ // intentionally NOT added to supportedProviders
+ }
+
+ /**
+ * Creates a transient (non-registered) {@link Provider} with the given name.
+ *
+ * The new instance is not added to {@code supportedProviders}, so it
+ * will never be returned by {@link #getProvider(String)} and will not pollute the
+ * global provider registry. Use this for dynamic / extension-backed providers
+ * whose names are only known at runtime (e.g. NetworkOrchestrator extensions).
+ *
+ * @param name the provider name (typically the extension name)
+ * @return a transient {@link Provider} instance with the given name
+ */
+ public static Provider createTransientProvider(String name) {
+ return new Provider(name);
+ }
+
@Override public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("name", name)
.toString();
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!(obj instanceof Provider)) return false;
+ Provider provider = (Provider) obj;
+ return this.name.equals(provider.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
}
public static class Capability {
@@ -510,4 +548,6 @@ public void setIp6Address(String ip6Address) {
Integer getPrivateMtu();
Integer getNetworkCidrSize();
+
+ boolean getKeepMacAddressOnPublicNic();
}
diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java
index c212e6319eb4..7e1a07ebeb69 100644
--- a/api/src/main/java/com/cloud/network/NetworkModel.java
+++ b/api/src/main/java/com/cloud/network/NetworkModel.java
@@ -187,6 +187,8 @@ public interface NetworkModel {
boolean canElementEnableIndividualServices(Provider provider);
+ boolean canElementEnableIndividualServicesByName(String providerName);
+
boolean areServicesSupportedInNetwork(long networkId, Service... services);
boolean isNetworkSystem(Network network);
@@ -237,6 +239,18 @@ public interface NetworkModel {
String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware);
+ /**
+ * Resolves a provider name to a {@link Provider} instance.
+ * For known static providers, delegates to {@link Provider#getProvider(String)}.
+ * For dynamically-registered NetworkOrchestrator extension providers whose names
+ * are not in the static registry, returns a transient {@link Provider} with the
+ * given name so callers can still dispatch correctly.
+ *
+ * @param providerName the provider name from {@code ntwk_service_map} or similar
+ * @return a {@link Provider} instance, or {@code null} if not resolvable
+ */
+ Provider resolveProvider(String providerName);
+
/**
* @param providerName
* @return
diff --git a/api/src/main/java/com/cloud/network/NetworkProfile.java b/api/src/main/java/com/cloud/network/NetworkProfile.java
index 2e8efb489308..d690344a0e38 100644
--- a/api/src/main/java/com/cloud/network/NetworkProfile.java
+++ b/api/src/main/java/com/cloud/network/NetworkProfile.java
@@ -385,6 +385,11 @@ public Integer getNetworkCidrSize() {
return networkCidrSize;
}
+ @Override
+ public boolean getKeepMacAddressOnPublicNic() {
+ return true;
+ }
+
@Override
public String toString() {
return String.format("NetworkProfile %s",
diff --git a/api/src/main/java/com/cloud/network/NetworkRuleApplier.java b/api/src/main/java/com/cloud/network/NetworkRuleApplier.java
index b9942e71eb26..69b712bc6ca2 100644
--- a/api/src/main/java/com/cloud/network/NetworkRuleApplier.java
+++ b/api/src/main/java/com/cloud/network/NetworkRuleApplier.java
@@ -21,8 +21,13 @@
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
public interface NetworkRuleApplier {
- public boolean applyRules(Network network, FirewallRule.Purpose purpose, List extends FirewallRule> rules) throws ResourceUnavailableException;
+ default boolean applyRules(Network network, FirewallRule.Purpose purpose, List extends FirewallRule> rules) throws ResourceUnavailableException {
+ return applyRules(network, null, purpose, rules);
+ }
+
+ boolean applyRules(Network network, Vpc vpc, FirewallRule.Purpose purpose, List extends FirewallRule> rules) throws ResourceUnavailableException;
}
diff --git a/api/src/main/java/com/cloud/network/NetworkService.java b/api/src/main/java/com/cloud/network/NetworkService.java
index 742206c7e3bf..c32bb711c0f2 100644
--- a/api/src/main/java/com/cloud/network/NetworkService.java
+++ b/api/src/main/java/com/cloud/network/NetworkService.java
@@ -232,7 +232,7 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
/**
* Requests an IP address for the guest NIC
*/
- NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair) throws InsufficientAddressCapacityException;
+ NicSecondaryIp allocateSecondaryGuestIP(long nicId, IpAddresses requestedIpPair, String description) throws InsufficientAddressCapacityException;
boolean releaseSecondaryIpFromNic(long ipAddressId);
@@ -279,4 +279,6 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
IpAddresses getIpAddressesFromIps(String ipAddress, String ip6Address, String macAddress);
String getNicVlanValueForExternalVm(NicTO nic);
+
+ Long getPreferredNetworkIdForPublicIpRuleAssignment(IpAddress ip, Long networkId);
}
diff --git a/api/src/main/java/com/cloud/network/Networks.java b/api/src/main/java/com/cloud/network/Networks.java
index 5f767686dc97..61a1c820723f 100644
--- a/api/src/main/java/com/cloud/network/Networks.java
+++ b/api/src/main/java/com/cloud/network/Networks.java
@@ -81,7 +81,11 @@ public String getValueFrom(URI uri) {
return uri == null ? null : uri.getAuthority();
}
},
- Vswitch("vs", String.class), LinkLocal(null, null), Vnet("vnet", Long.class), Storage("storage", Integer.class), Lswitch("lswitch", String.class) {
+ Vswitch("vs", String.class),
+ LinkLocal(null, null),
+ Vnet("vnet", Long.class),
+ Storage("storage", Integer.class),
+ Lswitch("lswitch", String.class) {
@Override
public URI toUri(T value) {
try {
@@ -99,7 +103,8 @@ public String getValueFrom(URI uri) {
return uri == null ? null : uri.getSchemeSpecificPart();
}
},
- Mido("mido", String.class), Pvlan("pvlan", String.class),
+ Mido("mido", String.class),
+ Pvlan("pvlan", String.class),
Vxlan("vxlan", Long.class) {
@Override
public URI toUri(T value) {
diff --git a/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java b/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
index 9676badb4e90..d3804cd29daf 100644
--- a/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
+++ b/api/src/main/java/com/cloud/network/PhysicalNetworkTrafficType.java
@@ -41,4 +41,6 @@ public interface PhysicalNetworkTrafficType extends InternalIdentity, Identity {
String getHypervNetworkLabel();
String getOvm3NetworkLabel();
+
+ String getVlan();
}
diff --git a/api/src/main/java/com/cloud/network/element/DnsServiceProvider.java b/api/src/main/java/com/cloud/network/element/DnsServiceProvider.java
index 7abce537221c..2942e76965a7 100644
--- a/api/src/main/java/com/cloud/network/element/DnsServiceProvider.java
+++ b/api/src/main/java/com/cloud/network/element/DnsServiceProvider.java
@@ -33,4 +33,6 @@ boolean configDnsSupportForSubnet(Network network, NicProfile nic, VirtualMachin
throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
boolean removeDnsSupportForSubnet(Network network) throws ResourceUnavailableException;
+
+ default boolean removeDnsEntry(Network network, NicProfile nic, VirtualMachineProfile vmProfile) throws ResourceUnavailableException { return true; }
}
diff --git a/api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java b/api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java
index c091142d9353..6b0f932e8c22 100644
--- a/api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java
+++ b/api/src/main/java/com/cloud/network/element/FirewallServiceProvider.java
@@ -21,14 +21,20 @@
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
public interface FirewallServiceProvider extends NetworkElement {
/**
- * Apply rules
- * @param network
- * @param rules
- * @return
- * @throws ResourceUnavailableException
+ * Apply firewall rules in a network context.
*/
- boolean applyFWRules(Network network, List extends FirewallRule> rules) throws ResourceUnavailableException;
+ default boolean applyFWRules(Network network, List extends FirewallRule> rules) throws ResourceUnavailableException {
+ return false;
+ }
+
+ /**
+ * Apply firewall rules in a VPC context.
+ */
+ default boolean applyFWRulesInVPC(Vpc vpc, List extends FirewallRule> rules) throws ResourceUnavailableException {
+ return false;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/element/NetworkElement.java b/api/src/main/java/com/cloud/network/element/NetworkElement.java
index cb0fc2fca981..67be7b9ba2e2 100644
--- a/api/src/main/java/com/cloud/network/element/NetworkElement.java
+++ b/api/src/main/java/com/cloud/network/element/NetworkElement.java
@@ -146,4 +146,8 @@ boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, Reser
* @return true/false
*/
boolean verifyServicesCombination(Set services);
+
+ default boolean rollingRestartSupported() {
+ return true;
+ }
}
diff --git a/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
index 0bf06be15d87..b7fe3b26761c 100644
--- a/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
+++ b/api/src/main/java/com/cloud/network/lb/LoadBalancingRulesService.java
@@ -108,7 +108,7 @@ LoadBalancer createPublicLoadBalancerRule(String xId, String name, String descri
/**
* Assign a virtual machine or list of virtual machines, or Map of to a load balancer.
*/
- boolean assignToLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap, boolean isAutoScaleVM);
+ boolean assignToLoadBalancer(long lbRuleId, List vmIds, Map> vmIdIpMap, Map vmIdNetworkMap, boolean isAutoScaleVM);
boolean assignSSLCertToLoadBalancerRule(Long lbRuleId, String certName, String publicCert, String privateKey);
diff --git a/api/src/main/java/com/cloud/network/rules/FirewallRule.java b/api/src/main/java/com/cloud/network/rules/FirewallRule.java
index 369c6aa57eb8..38ba009163ce 100644
--- a/api/src/main/java/com/cloud/network/rules/FirewallRule.java
+++ b/api/src/main/java/com/cloud/network/rules/FirewallRule.java
@@ -69,7 +69,9 @@ enum TrafficType {
State getState();
- long getNetworkId();
+ Long getNetworkId();
+
+ Long getVpcId();
Long getSourceIpAddressId();
diff --git a/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java b/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
index 56a0622a52ba..5143611ee828 100644
--- a/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
+++ b/api/src/main/java/com/cloud/network/rules/LbStickinessMethod.java
@@ -108,8 +108,7 @@ public LbStickinessMethod(StickinessMethodType methodType, String description) {
}
public void addParam(String name, Boolean required, String description, Boolean isFlag) {
- /* FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
- // LbStickinessMethodParam param = new LbStickinessMethodParam(name, required, description);
+ /* is this still a valid comment: FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
LbStickinessMethodParam param = new LbStickinessMethodParam(name, required, " ", isFlag);
_paramList.add(param);
return;
@@ -133,7 +132,6 @@ public String getDescription() {
public void setDescription(String description) {
/* FIXME : UI is breaking if the capability string length is larger , temporarily description is commented out */
- //this.description = description;
this._description = " ";
}
}
diff --git a/api/src/main/java/com/cloud/network/vpc/Vpc.java b/api/src/main/java/com/cloud/network/vpc/Vpc.java
index b94089d2d433..a0686e2bf7d0 100644
--- a/api/src/main/java/com/cloud/network/vpc/Vpc.java
+++ b/api/src/main/java/com/cloud/network/vpc/Vpc.java
@@ -107,4 +107,6 @@ public enum State {
String getIp6Dns2();
boolean useRouterIpAsResolver();
+
+ boolean getKeepMacAddressOnPublicNic();
}
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
index 17f49bb36521..f84602232159 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java
@@ -84,4 +84,6 @@ public enum State {
NetworkOffering.RoutingMode getRoutingMode();
Boolean isSpecifyAsNumber();
+
+ boolean isConserveMode();
}
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
index 97b95339ecf3..891cfb02d9df 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
+import org.apache.cloudstack.api.command.admin.vpc.CloneVPCOfferingCmd;
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
@@ -34,12 +35,14 @@ public interface VpcProvisioningService {
VpcOffering createVpcOffering(CreateVPCOfferingCmd cmd);
+ VpcOffering cloneVPCOffering(CloneVPCOfferingCmd cmd);
+
VpcOffering createVpcOffering(String name, String displayText, List supportedServices,
Map> serviceProviders,
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
Long serviceOfferingId, String externalProvider, NetworkOffering.NetworkMode networkMode,
List domainIds, List zoneIds, VpcOffering.State state,
- NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber);
+ NetworkOffering.RoutingMode routingMode, boolean specifyAsNumber, boolean conserveMode);
Pair,Integer> listVpcOfferings(ListVPCOfferingsCmd cmd);
diff --git a/api/src/main/java/com/cloud/network/vpc/VpcService.java b/api/src/main/java/com/cloud/network/vpc/VpcService.java
index c1546609d2b7..3d0ba43263f5 100644
--- a/api/src/main/java/com/cloud/network/vpc/VpcService.java
+++ b/api/src/main/java/com/cloud/network/vpc/VpcService.java
@@ -58,7 +58,7 @@ public interface VpcService {
*/
Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc, Integer publicMtu, Integer cidrSize,
- Long asNumber, List bgpPeerIds, Boolean useVrIpResolver) throws ResourceAllocationException;
+ Long asNumber, List bgpPeerIds, Boolean useVrIpResolver, boolean keepMacAddressOnPublicNic) throws ResourceAllocationException;
/**
* Persists VPC record in the database
@@ -104,7 +104,7 @@ Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, Strin
* @throws ResourceUnavailableException if during restart some resources may not be available
* @throws InsufficientCapacityException if for instance no address space, compute or storage is sufficiently available
*/
- Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc, Integer mtu, String sourceNatIp) throws ResourceUnavailableException, InsufficientCapacityException;
+ Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc, Integer mtu, String sourceNatIp, Boolean keepMacAddressOnPublicNic) throws ResourceUnavailableException, InsufficientCapacityException;
/**
* Lists VPC(s) based on the parameters passed to the API call
diff --git a/api/src/main/java/com/cloud/offering/DiskOfferingInfo.java b/api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
index 12dcf423e34f..197565a1fccb 100644
--- a/api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
+++ b/api/src/main/java/com/cloud/offering/DiskOfferingInfo.java
@@ -23,6 +23,7 @@ public class DiskOfferingInfo {
private Long _size;
private Long _minIops;
private Long _maxIops;
+ private Long _kmsKeyId;
public DiskOfferingInfo() {
}
@@ -38,6 +39,14 @@ public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long
_maxIops = maxIops;
}
+ public DiskOfferingInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long kmsKeyId) {
+ _diskOffering = diskOffering;
+ _size = size;
+ _minIops = minIops;
+ _maxIops = maxIops;
+ _kmsKeyId = kmsKeyId;
+ }
+
public void setDiskOffering(DiskOffering diskOffering) {
_diskOffering = diskOffering;
}
@@ -69,4 +78,12 @@ public void setMaxIops(Long maxIops) {
public Long getMaxIops() {
return _maxIops;
}
+
+ public void setKmsKeyId(Long kmsKeyId) {
+ _kmsKeyId = kmsKeyId;
+ }
+
+ public Long getKmsKeyId() {
+ return _kmsKeyId;
+ }
}
diff --git a/api/src/main/java/com/cloud/server/ManagementService.java b/api/src/main/java/com/cloud/server/ManagementService.java
index 51737546ffad..bcca229c06bc 100644
--- a/api/src/main/java/com/cloud/server/ManagementService.java
+++ b/api/src/main/java/com/cloud/server/ManagementService.java
@@ -71,7 +71,6 @@
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.config.ConfigurationGroup;
-import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.alert.Alert;
import com.cloud.capacity.Capacity;
@@ -108,14 +107,6 @@
public interface ManagementService {
static final String Name = "management-server";
- ConfigKey JsInterpretationEnabled = new ConfigKey<>("Hidden"
- , Boolean.class
- , "js.interpretation.enabled"
- , "false"
- , "Enable/Disable all JavaScript interpretation related functionalities to create or update Javascript rules."
- , false
- , ConfigKey.Scope.Global);
-
/**
* returns the a map of the names/values in the configuration table
*
@@ -534,6 +525,4 @@ VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableE
boolean removeManagementServer(RemoveManagementServerCmd cmd);
- void checkJsInterpretationAllowedIfNeededForParameterValue(String paramName, boolean paramValue);
-
}
diff --git a/api/src/main/java/com/cloud/server/ResourceTag.java b/api/src/main/java/com/cloud/server/ResourceTag.java
index b3026deceff8..32305753f1ae 100644
--- a/api/src/main/java/com/cloud/server/ResourceTag.java
+++ b/api/src/main/java/com/cloud/server/ResourceTag.java
@@ -16,14 +16,14 @@
// under the License.
package com.cloud.server;
-import org.apache.cloudstack.acl.ControlledEntity;
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
public interface ResourceTag extends ControlledEntity, Identity, InternalIdentity {
// FIXME - extract enum to another interface as its used both by resourceTags and resourceMetaData code
@@ -70,7 +70,7 @@ public enum ResourceObjectType {
GuestOs(false, true),
NetworkOffering(false, true),
VpcOffering(true, false),
- Domain(false, false, true),
+ Domain(true, false, true),
ObjectStore(false, false, true);
diff --git a/api/src/main/java/com/cloud/storage/Storage.java b/api/src/main/java/com/cloud/storage/Storage.java
index 1ad3731b9eaa..3511b4e88cb9 100644
--- a/api/src/main/java/com/cloud/storage/Storage.java
+++ b/api/src/main/java/com/cloud/storage/Storage.java
@@ -35,7 +35,8 @@ public static enum ImageFormat {
VDI(true, true, false, "vdi"),
TAR(false, false, false, "tar"),
ZIP(false, false, false, "zip"),
- DIR(false, false, false, "dir");
+ DIR(false, false, false, "dir"),
+ PNG(false, false, false, "png");
private final boolean supportThinProvisioning;
private final boolean supportSparse;
@@ -128,7 +129,7 @@ public static enum FileSystem {
public static enum TemplateType {
ROUTING, // Router template
SYSTEM, /* routing, system vm template */
- BUILTIN, /* buildin template */
+ BUILTIN, /* builtin template */
PERHOST, /* every host has this template, don't need to install it in secondary storage */
USER, /* User supplied template/iso */
VNF, /* VNFs (virtual network functions) template */
@@ -170,6 +171,7 @@ public static enum StoragePoolType {
ISO(false, false, EncryptionSupport.Unsupported), // for iso image
LVM(false, false, EncryptionSupport.Unsupported), // XenServer local LVM SR
CLVM(true, false, EncryptionSupport.Unsupported),
+ CLVM_NG(true, false, EncryptionSupport.Hypervisor),
RBD(true, true, EncryptionSupport.Unsupported), // http://libvirt.org/storage.html#StorageBackendRBD
SharedMountPoint(true, true, EncryptionSupport.Hypervisor),
VMFS(true, true, EncryptionSupport.Unsupported), // VMware VMFS storage
diff --git a/api/src/main/java/com/cloud/storage/Volume.java b/api/src/main/java/com/cloud/storage/Volume.java
index c7fbdb0a5445..89298e04587f 100644
--- a/api/src/main/java/com/cloud/storage/Volume.java
+++ b/api/src/main/java/com/cloud/storage/Volume.java
@@ -60,7 +60,9 @@ enum State {
UploadError(false, "Volume upload encountered some error"),
UploadAbandoned(false, "Volume upload is abandoned since the upload was never initiated within a specified time"),
Attaching(true, "The volume is attaching to a VM from Ready state."),
- Restoring(true, "The volume is being restored from backup.");
+ Restoring(true, "The volume is being restored from backup."),
+ Consolidating(true, "The volume is being flattened."),
+ RestoreError(false, "The volume restore encountered an error.");
boolean _transitional;
@@ -153,6 +155,10 @@ public String getDescription() {
s_fsm.addTransition(new StateMachine2.Transition(Destroy, Event.RestoreRequested, Restoring, null));
s_fsm.addTransition(new StateMachine2.Transition(Restoring, Event.RestoreSucceeded, Ready, null));
s_fsm.addTransition(new StateMachine2.Transition(Restoring, Event.RestoreFailed, Ready, null));
+ s_fsm.addTransition(new StateMachine2.Transition<>(Ready, Event.ConsolidationRequested, Consolidating, null));
+ s_fsm.addTransition(new StateMachine2.Transition<>(Consolidating, Event.OperationSucceeded, Ready, null));
+ s_fsm.addTransition(new StateMachine2.Transition<>(Consolidating, Event.OperationFailed, RestoreError, null));
+ s_fsm.addTransition(new StateMachine2.Transition<>(RestoreError, Event.RestoreFailed, RestoreError, null));
}
}
@@ -179,7 +185,8 @@ enum Event {
OperationTimeout,
RestoreRequested,
RestoreSucceeded,
- RestoreFailed;
+ RestoreFailed,
+ ConsolidationRequested
}
/**
@@ -275,6 +282,14 @@ enum Event {
void setPassphraseId(Long id);
+ Long getKmsKeyId();
+
+ void setKmsKeyId(Long id);
+
+ Long getKmsWrappedKeyId();
+
+ void setKmsWrappedKeyId(Long id);
+
String getEncryptFormat();
void setEncryptFormat(String encryptFormat);
diff --git a/api/src/main/java/com/cloud/storage/VolumeApiService.java b/api/src/main/java/com/cloud/storage/VolumeApiService.java
index 19c2ebe455a5..372eb0385618 100644
--- a/api/src/main/java/com/cloud/storage/VolumeApiService.java
+++ b/api/src/main/java/com/cloud/storage/VolumeApiService.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
+import com.cloud.dc.DataCenter;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.offering.DiskOffering;
import com.cloud.user.Account;
@@ -56,9 +57,9 @@ public interface VolumeApiService {
Boolean.class,
"use.https.to.upload",
"true",
- "Determines the protocol (HTTPS or HTTP) ACS will use to generate links to upload ISOs, volumes, and templates. When set as 'true', ACS will use protocol HTTPS, otherwise, it will use protocol HTTP. Default value is 'true'.",
+ "Controls whether upload links for ISOs, volumes, and templates use HTTPS (true, default) or HTTP (false). After changing this setting, the Secondary Storage VM (SSVM) must be recreated",
true,
- ConfigKey.Scope.StoragePool);
+ ConfigKey.Scope.Zone);
/**
* Creates the database object for a volume based on the given criteria
@@ -70,6 +71,10 @@ public interface VolumeApiService {
*/
Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException;
+ Volume allocVolume(long ownerId, Long zoneId, Long diskOfferingId, Long vmId, Long snapshotId, String name,
+ Long cmdSize, Boolean displayVolume, Long cmdMinIops, Long cmdMaxIops, String customId, Long kmsKeyId)
+ throws ResourceAllocationException;
+
/**
* Creates the volume based on the given criteria
*
@@ -80,6 +85,8 @@ public interface VolumeApiService {
*/
Volume createVolume(CreateVolumeCmd cmd);
+ Volume createVolume(long volumeId, Long vmId, Long snapshotId, Long storageId, Boolean display);
+
/**
* Resizes the volume based on the given criteria
*
@@ -107,7 +114,7 @@ public interface VolumeApiService {
Volume attachVolumeToVM(AttachVolumeCmd command);
- Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId, Boolean allowAttachForSharedFS);
+ Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId, Boolean allowAttachForSharedFS, boolean allowAttachOnRestoring);
Volume detachVolumeViaDestroyVM(long vmId, long volumeId);
@@ -182,7 +189,7 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
boolean validateConditionsToReplaceDiskOfferingOfVolume(Volume volume, DiskOffering newDiskOffering, StoragePool destPool);
- Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge);
+ Volume destroyVolume(long volumeId, Account caller, boolean expunge, boolean forceExpunge, Boolean countDisplayFalseInResourceCount);
void destroyVolume(long volumeId);
@@ -203,4 +210,6 @@ Volume updateVolume(long volumeId, String path, String state, Long storageId,
Pair checkAndRepairVolume(CheckAndRepairVolumeCmd cmd) throws ResourceAllocationException;
Long getVolumePhysicalSize(Storage.ImageFormat format, String path, String chainInfo);
+
+ Long getCustomDiskOfferingIdForVolumeUpload(Account owner, DataCenter zone, boolean encryptEnabledOnly);
}
diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java
index 09fe5ffc0590..fc450e9179c5 100644
--- a/api/src/main/java/com/cloud/user/AccountService.java
+++ b/api/src/main/java/com/cloud/user/AccountService.java
@@ -21,12 +21,13 @@
import com.cloud.utils.Pair;
import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RolePermissionEntity;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
+import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd;
-import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
-import org.apache.cloudstack.api.command.admin.user.RegisterUserKeyCmd;
-import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
import com.cloud.dc.DataCenter;
import com.cloud.domain.Domain;
@@ -35,7 +36,16 @@
import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUserKeyRulesCmd;
+import org.apache.cloudstack.api.command.admin.user.ListUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterUserKeysCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.cloudstack.api.response.ApiKeyPairResponse;
+import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.auth.UserTwoFactorAuthenticator;
+import org.apache.cloudstack.backup.BackupOffering;
public interface AccountService {
@@ -58,7 +68,8 @@ UserAccount createUserAccount(String userName, String password, String firstName
User getSystemUser();
- User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
+ User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone,
+ String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired);
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
User.Source source);
@@ -77,10 +88,16 @@ User createUser(String userName, String password, String firstName, String lastN
Account getActiveAccountById(long accountId);
+ Account getActiveAccountByUuid(String accountUuid);
+
Account getAccount(long accountId);
+ Account getAccountByUuid(String accountUuid);
+
User getActiveUser(long userId);
+ User getOneActiveUserForAccount(Account account);
+
User getUserIncludingRemoved(long userId);
boolean isRootAdmin(Long accountId);
@@ -95,7 +112,7 @@ User createUser(String userName, String password, String firstName, String lastN
void markUserRegistered(long userId);
- public String[] createApiKeyAndSecretKey(RegisterUserKeyCmd cmd);
+ ApiKeyPair createApiKeyAndSecretKey(RegisterUserKeysCmd cmd);
public String[] createApiKeyAndSecretKey(final long userId);
@@ -115,13 +132,19 @@ User createUser(String userName, String password, String firstName, String lastN
void checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException;
+ void checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException;
+
void checkAccess(User user, ControlledEntity entity);
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource);
- Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+ void validateCallingUserHasAccessToDesiredUser(Long userId);
+
+ Long finalizeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
+
+ Long finalizeAccountId(Long accountId, String accountName, Long domainId, Long projectId);
/**
* returns the user account object for a given user id
@@ -130,9 +153,15 @@ User createUser(String userName, String password, String firstName, String lastN
*/
UserAccount getUserAccountById(Long userId);
- public Pair> getKeys(GetUserKeysCmd cmd);
+ Pair> getKeys(GetUserKeysCmd cmd);
+
+ ListResponse listKeys(ListUserKeysCmd cmd);
+
+ List listKeyRules(ListUserKeyRulesCmd cmd);
+
+ void deleteApiKey(DeleteUserKeysCmd cmd);
- public Pair> getKeys(Long userId);
+ void deleteApiKey(ApiKeyPair id);
/**
* Lists user two-factor authentication provider plugins
@@ -147,4 +176,13 @@ User createUser(String userName, String password, String firstName, String lastN
*/
UserTwoFactorAuthenticator getUserTwoFactorAuthenticationProvider(final Long domainId);
+ ApiKeyPair getLatestUserKeyPair(Long userId);
+
+ ApiKeyPair getKeyPairById(Long id);
+
+ ApiKeyPair getKeyPairByApiKey(String apiKey);
+
+ String getAccessingApiKey(BaseCmd cmd);
+
+ List getAllKeypairPermissions(String apiKey);
}
diff --git a/api/src/main/java/com/cloud/user/ApiKeyPairState.java b/api/src/main/java/com/cloud/user/ApiKeyPairState.java
new file mode 100644
index 000000000000..63405c62e320
--- /dev/null
+++ b/api/src/main/java/com/cloud/user/ApiKeyPairState.java
@@ -0,0 +1,21 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.user;
+
+public enum ApiKeyPairState {
+ ENABLED, REMOVED, EXPIRED
+}
diff --git a/api/src/main/java/com/cloud/user/ResourceLimitService.java b/api/src/main/java/com/cloud/user/ResourceLimitService.java
index 9c493fb383c9..89128f87829e 100644
--- a/api/src/main/java/com/cloud/user/ResourceLimitService.java
+++ b/api/src/main/java/com/cloud/user/ResourceLimitService.java
@@ -254,14 +254,14 @@ public interface ResourceLimitService {
void updateTaggedResourceLimitsAndCountsForAccounts(List responses, String tag);
void updateTaggedResourceLimitsAndCountsForDomains(List responses, String tag);
void checkVolumeResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List reservations) throws ResourceAllocationException;
- List getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering);
+ List getResourceLimitStorageTagsForResourceCountOperation(Boolean display, DiskOffering diskOffering, Boolean enforceResourceLimitOnDisplayFalse);
void checkVolumeResourceLimitForDiskOfferingChange(Account owner, Boolean display, Long currentSize, Long newSize,
DiskOffering currentOffering, DiskOffering newOffering, List reservations) throws ResourceAllocationException;
void checkPrimaryStorageResourceLimit(Account owner, Boolean display, Long size, DiskOffering diskOffering, List reservations) throws ResourceAllocationException;
void incrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
- void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
+ void decrementVolumeResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering, Boolean countDisplayFalseInResourceCount);
void updateVmResourceCountForTemplateChange(long accountId, Boolean display, ServiceOffering offering, VirtualMachineTemplate currentTemplate, VirtualMachineTemplate newTemplate);
@@ -276,8 +276,8 @@ void updateVolumeResourceCountForDiskOfferingChange(long accountId, Boolean disp
void incrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
void decrementVolumePrimaryStorageResourceCount(long accountId, Boolean display, Long size, DiskOffering diskOffering);
void checkVmResourceLimit(Account owner, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, List reservations) throws ResourceAllocationException;
- void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
- void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template);
+ void incrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Boolean countDisplayFalseInResourceLimit);
+ void decrementVmResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Boolean countDisplayFalseInResourceCount);
void checkVmResourceLimitsForServiceOfferingChange(Account owner, Boolean display, Long currentCpu, Long newCpu,
Long currentMemory, Long newMemory, ServiceOffering currentOffering, ServiceOffering newOffering, VirtualMachineTemplate template, List reservations) throws ResourceAllocationException;
diff --git a/api/src/main/java/com/cloud/user/User.java b/api/src/main/java/com/cloud/user/User.java
index 041b39ad2729..da7245a47980 100644
--- a/api/src/main/java/com/cloud/user/User.java
+++ b/api/src/main/java/com/cloud/user/User.java
@@ -65,14 +65,6 @@ public enum Source {
public void setState(Account.State state);
- public String getApiKey();
-
- public void setApiKey(String apiKey);
-
- public String getSecretKey();
-
- public void setSecretKey(String secretKey);
-
public String getTimezone();
public void setTimezone(String timezone);
diff --git a/api/src/main/java/com/cloud/user/UserAccount.java b/api/src/main/java/com/cloud/user/UserAccount.java
index e6b07fb371eb..5736244e3259 100644
--- a/api/src/main/java/com/cloud/user/UserAccount.java
+++ b/api/src/main/java/com/cloud/user/UserAccount.java
@@ -39,10 +39,6 @@ public interface UserAccount extends InternalIdentity {
String getState();
- String getApiKey();
-
- String getSecretKey();
-
Date getCreated();
Date getRemoved();
diff --git a/api/src/main/java/com/cloud/vm/DiskProfile.java b/api/src/main/java/com/cloud/vm/DiskProfile.java
index 971ebde496e4..766573d4d40b 100644
--- a/api/src/main/java/com/cloud/vm/DiskProfile.java
+++ b/api/src/main/java/com/cloud/vm/DiskProfile.java
@@ -82,7 +82,7 @@ public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType)
null);
this.hyperType = hyperType;
this.provisioningType = offering.getProvisioningType();
- this.requiresEncryption = offering.getEncrypt() || vol.getPassphraseId() != null;
+ this.requiresEncryption = offering.getEncrypt() || vol.getPassphraseId() != null || vol.getKmsKeyId() != null;
}
public DiskProfile(DiskProfile dp) {
diff --git a/api/src/main/java/com/cloud/vm/Nic.java b/api/src/main/java/com/cloud/vm/Nic.java
index afc44b8d39fa..3722e5769c92 100644
--- a/api/src/main/java/com/cloud/vm/Nic.java
+++ b/api/src/main/java/com/cloud/vm/Nic.java
@@ -33,6 +33,11 @@
* Nic represents one nic on the VM.
*/
public interface Nic extends Identity, InternalIdentity {
+
+ interface Topics {
+ String NIC_LIFECYCLE = "nic.lifecycle";
+ }
+
enum Event {
ReservationRequested, ReleaseRequested, CancelRequested, OperationCompleted, OperationFailed,
}
@@ -162,4 +167,6 @@ public enum ReservationStrategy {
String getIPv6Address();
Integer getMtu();
+
+ boolean isEnabled();
}
diff --git a/api/src/main/java/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java
index a0c80ceb1bfb..54a32bbcb181 100644
--- a/api/src/main/java/com/cloud/vm/NicProfile.java
+++ b/api/src/main/java/com/cloud/vm/NicProfile.java
@@ -52,6 +52,7 @@ public class NicProfile implements InternalIdentity, Serializable {
boolean defaultNic;
Integer networkRate;
boolean isSecurityGroupEnabled;
+ boolean enabled;
Integer orderIndex;
@@ -87,6 +88,7 @@ public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri,
broadcastType = network.getBroadcastDomainType();
trafficType = network.getTrafficType();
format = nic.getAddressFormat();
+ enabled = nic.isEnabled();
iPv4Address = nic.getIPv4Address();
iPv4Netmask = nic.getIPv4Netmask();
@@ -414,6 +416,14 @@ public void setIpv4AllocationRaceCheck(boolean ipv4AllocationRaceCheck) {
this.ipv4AllocationRaceCheck = ipv4AllocationRaceCheck;
}
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
//
// OTHER METHODS
//
@@ -453,6 +463,6 @@ public String toString() {
return String.format("NicProfile %s",
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
this, "id", "uuid", "vmId", "deviceId",
- "broadcastUri", "reservationId", "iPv4Address"));
+ "broadcastType", "broadcastUri", "reservationId", "iPv4Address"));
}
}
diff --git a/api/src/main/java/com/cloud/vm/NicSecondaryIp.java b/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
index 2856e0aea756..d25627c1782d 100644
--- a/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
+++ b/api/src/main/java/com/cloud/vm/NicSecondaryIp.java
@@ -38,6 +38,8 @@ public interface NicSecondaryIp extends ControlledEntity, Identity, InternalIden
String getIp6Address();
+ String getDescription();
+
long getNetworkId();
long getVmId();
diff --git a/api/src/main/java/com/cloud/vm/UserVmService.java b/api/src/main/java/com/cloud/vm/UserVmService.java
index 4ad1ffb755bc..5864e91cd7f4 100644
--- a/api/src/main/java/com/cloud/vm/UserVmService.java
+++ b/api/src/main/java/com/cloud/vm/UserVmService.java
@@ -40,6 +40,7 @@
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
+import org.apache.cloudstack.api.command.user.vm.UpdateVmNicCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
@@ -74,10 +75,11 @@ public interface UserVmService {
* Destroys one virtual machine
*
* @param cmd the API Command Object containg the parameters to use for this service action
+ * @param checkExpunge
* @throws ConcurrentOperationException
* @throws ResourceUnavailableException
*/
- UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException;
+ UserVm destroyVm(DestroyVMCmd cmd, boolean checkExpunge) throws ResourceUnavailableException, ConcurrentOperationException;
/**
* Destroys one virtual machine
@@ -152,6 +154,8 @@ void startVirtualMachineForHA(VirtualMachine vm, Map sshKeyPairs, Map requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
List affinityGroupIdList, Map customParameter, String customId, Map> dhcpOptionMap,
Map dataDiskTemplateToDiskOfferingMap,
- Map userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
+ Map userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
@@ -302,7 +306,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
List securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List dataDiskInfoList, String group, HypervisorType hypervisor,
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List sshKeyPairs, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
List affinityGroupIdList, Map customParameters, String customId, Map> dhcpOptionMap,
- Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
+ Map dataDiskTemplateToDiskOfferingMap, Map userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
/**
* Creates a User VM in Advanced Zone (Security Group feature is disabled)
@@ -374,7 +378,7 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe
String hostName, String displayName, Long diskOfferingId, Long diskSize, List dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
Long userDataId, String userDataDetails, List sshKeyPairs, Map requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List affinityGroupIdList,
Map customParameters, String customId, Map> dhcpOptionMap, Map dataDiskTemplateToDiskOfferingMap,
- Map templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot)
+ Map templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Long rootDiskKmsKeyId, Volume volume, Snapshot snapshot)
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
diff --git a/api/src/main/java/com/cloud/vm/VirtualMachine.java b/api/src/main/java/com/cloud/vm/VirtualMachine.java
index 41c9a864c9d0..3adcc85d28a1 100644
--- a/api/src/main/java/com/cloud/vm/VirtualMachine.java
+++ b/api/src/main/java/com/cloud/vm/VirtualMachine.java
@@ -58,7 +58,10 @@ public enum State {
Error(false, "VM is in error"),
Unknown(false, "VM state is unknown."),
Shutdown(false, "VM state is shutdown from inside"),
- Restoring(true, "VM is being restored from backup");
+ Restoring(true, "VM is being restored from backup"),
+ BackingUp(true, "VM is being backed up"),
+ BackupError(false, "VM backup is in an inconsistent state. Operator should analyse the logs and restore the VM"),
+ RestoreError(false, "VM restore left the VM in an inconsistent state. Operator should analyse the logs and restore the VM");
private final boolean _transitional;
String _description;
@@ -134,6 +137,14 @@ public static StateMachine2 getStat
s_fsm.addTransition(new Transition(State.Destroyed, Event.RestoringRequested, State.Restoring, null));
s_fsm.addTransition(new Transition(State.Restoring, Event.RestoringSuccess, State.Stopped, null));
s_fsm.addTransition(new Transition(State.Restoring, Event.RestoringFailed, State.Stopped, null));
+ s_fsm.addTransition(new Transition<>(State.Running, Event.BackupRequested, State.BackingUp, null));
+ s_fsm.addTransition(new Transition<>(State.Stopped, Event.BackupRequested, State.BackingUp, null));
+ s_fsm.addTransition(new Transition<>(State.BackingUp, Event.BackupSucceededRunning, State.Running, null));
+ s_fsm.addTransition(new Transition<>(State.BackingUp, Event.BackupSucceededStopped, State.Stopped, null));
+ s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToError, State.BackupError, null));
+ s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToRunning, State.Running, null));
+ s_fsm.addTransition(new Transition<>(State.BackingUp, Event.OperationFailedToStopped, State.Stopped, null));
+ s_fsm.addTransition(new Transition(State.RestoreError, Event.RestoringFailed, State.RestoreError, null));
s_fsm.addTransition(new Transition(State.Starting, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, Arrays.asList(new Impact[]{Impact.USAGE})));
s_fsm.addTransition(new Transition(State.Stopping, VirtualMachine.Event.FollowAgentPowerOnReport, State.Running, null));
@@ -212,6 +223,8 @@ public enum Event {
ExpungeOperation,
OperationSucceeded,
OperationFailed,
+ OperationFailedToRunning,
+ OperationFailedToStopped,
OperationFailedToError,
OperationRetry,
AgentReportShutdowned,
@@ -221,6 +234,10 @@ public enum Event {
RestoringRequested,
RestoringFailed,
RestoringSuccess,
+ BackupRequested,
+ BackupSucceededStopped,
+ BackupSucceededRunning,
+ FinalizedBackupChain,
// added for new VMSync logic
FollowAgentPowerOnReport,
diff --git a/api/src/main/java/com/cloud/vm/VmDetailConstants.java b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
index db7665724973..877df55c6d67 100644
--- a/api/src/main/java/com/cloud/vm/VmDetailConstants.java
+++ b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
@@ -96,6 +96,7 @@ public interface VmDetailConstants {
String CKS_NODE_TYPE = "node";
String OFFERING = "offering";
String TEMPLATE = "template";
+ String AFFINITY_GROUP = "affinitygroup";
// VMware to KVM VM migrations specific
String VMWARE_TO_KVM_PREFIX = "vmware-to-kvm";
@@ -129,4 +130,20 @@ public interface VmDetailConstants {
String EXTERNAL_DETAIL_PREFIX = "External:";
String CLOUDSTACK_VM_DETAILS = "cloudstack.vm.details";
String CLOUDSTACK_VLAN = "cloudstack.vlan";
+
+ // KVM Checkpoints related
+ String ACTIVE_CHECKPOINT_ID = "active.checkpoint.id";
+ String ACTIVE_CHECKPOINT_CREATE_TIME = "active.checkpoint.create.time";
+ String LAST_CHECKPOINT_ID = "last.checkpoint.id";
+ String LAST_CHECKPOINT_CREATE_TIME = "last.checkpoint.create.time";
+
+ // KBOSS specific
+ String LINKED_VOLUMES_SECONDARY_STORAGE_UUIDS = "linkedVolumesSecondaryStorageUuids";
+ String VALIDATION_COMMAND = "backupValidationCommand";
+ String VALIDATION_COMMAND_ARGUMENTS = "backupValidationCommandArguments";
+ String VALIDATION_COMMAND_EXPECTED_RESULT = "backupValidationCommandExpectedResult";
+ String VALIDATION_COMMAND_TIMEOUT = "backupValidationCommandTimeout";
+ String VALIDATION_SCREENSHOT_WAIT = "backupValidationScreenshotWait";
+ String VALIDATION_BOOT_TIMEOUT = "backupValidationBootTimeout";
+ String LAST_KNOWN_STATE = "last_known_state";
}
diff --git a/api/src/main/java/com/cloud/vm/VmDiskInfo.java b/api/src/main/java/com/cloud/vm/VmDiskInfo.java
index b8779a8d77c6..97683e8397fa 100644
--- a/api/src/main/java/com/cloud/vm/VmDiskInfo.java
+++ b/api/src/main/java/com/cloud/vm/VmDiskInfo.java
@@ -33,6 +33,11 @@ public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIo
_deviceId = deviceId;
}
+ public VmDiskInfo(DiskOffering diskOffering, Long size, Long minIops, Long maxIops, Long deviceId, Long kmsKeyId) {
+ super(diskOffering, size, minIops, maxIops, kmsKeyId);
+ _deviceId = deviceId;
+ }
+
public Long getDeviceId() {
return _deviceId;
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java b/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
index 660f64f43ef2..286a3598e4fb 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/APIChecker.java
@@ -20,6 +20,7 @@
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
import java.util.List;
@@ -31,8 +32,8 @@ public interface APIChecker extends Adapter {
// If true, apiChecker has checked the operation
// If false, apiChecker is unable to handle the operation or not implemented
// On exception, checkAccess failed don't allow
- boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException;
- boolean checkAccess(Account account, String apiCommandName) throws PermissionDeniedException;
+ boolean checkAccess(User user, String apiCommandName, ApiKeyPairPermission... apiKeyPairPermissions) throws PermissionDeniedException;
+ boolean checkAccess(Account account, String apiCommandName, ApiKeyPairPermission... apiKeyPairPermissions) throws PermissionDeniedException;
/**
* Verifies if the account has permission for the given list of APIs and returns only the allowed ones.
*
@@ -43,4 +44,5 @@ public interface APIChecker extends Adapter {
*/
List getApisAllowedToUser(Role role, User user, List apiNames) throws PermissionDeniedException;
boolean isEnabled();
+ List getImplicitRolePermissions(RoleType roleType);
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java b/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
index 251c6b6d3f9e..f382b1c6964f 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RolePermissionEntity.java
@@ -21,7 +21,7 @@
import org.apache.cloudstack.api.InternalIdentity;
public interface RolePermissionEntity extends InternalIdentity, Identity {
- public enum Permission {
+ enum Permission {
ALLOW, DENY
}
Rule getRule();
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
index f041c8342aec..14e0a608a925 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleService.java
@@ -104,5 +104,26 @@ public interface RoleService {
List findAllPermissionsBy(Long roleId);
+ List findAllRolePermissionsEntityBy(Long roleId, boolean considerImplicitRules);
+
Permission getRolePermission(String permission);
+
+ int removeRolesIfNeeded(List extends Role> roles);
+
+ /**
+ * Checks if the role of the caller account has compatible permissions of the specified role permissions.
+ * For each permission of the {@param rolePermissionsToAccess}, the role of the caller needs to contain the same permission.
+ *
+ * @param rolePermissions the permissions of the caller role.
+ * @param rolePermissionsToAccess the permissions for the role that the caller role wants to access.
+ * @return True if the role can be accessed with the given permissions; false otherwise.
+ */
+ boolean roleHasPermission(Map rolePermissions, List rolePermissionsToAccess);
+
+ /**
+ * Given a list of role permissions, returns a {@link Map} containing the API name as the key and the {@link RolePermissionEntity} for the API as the value.
+ *
+ * @param rolePermissions Permissions for the role from role.
+ */
+ Map getRoleRulesAndPermissions(List rolePermissions);
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/RoleType.java b/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
index c721d52804c6..c33488cd9239 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/RoleType.java
@@ -132,10 +132,10 @@ public static Set fromCombinedMask(int combinedMask) {
* */
public static Account.Type getAccountTypeByRole(final Role role, final Account.Type defautAccountType) {
if (role != null) {
- LOGGER.debug(String.format("Role [%s] is not null; therefore, we use its Account type [%s].", role, defautAccountType));
+ LOGGER.debug("Role [{}] is not null; therefore, we use its Account type [{}].", role, defautAccountType);
return role.getRoleType().getAccountType();
}
- LOGGER.debug(String.format("Role is null; therefore, we use the default Account type [%s] value.", defautAccountType));
+ LOGGER.debug("Role is null; therefore, we use the default Account type [{}] value.", defautAccountType);
return defautAccountType;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/Rule.java b/api/src/main/java/org/apache/cloudstack/acl/Rule.java
index de64d855ccc1..ad01825a95f1 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/Rule.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/Rule.java
@@ -25,18 +25,18 @@
public final class Rule {
private final String rule;
- private final Pattern compiledPattern;
+ private final Pattern matchingPattern;
private final static Pattern ALLOWED_PATTERN = Pattern.compile("^[a-zA-Z0-9*]+$");
public Rule(final String rule) {
validate(rule);
this.rule = rule;
- this.compiledPattern = Pattern.compile(rule.replace("*", "\\w*"), Pattern.CASE_INSENSITIVE);
+ matchingPattern = Pattern.compile(rule.toLowerCase().replace("*", "(\\w*\\*?)+"));
}
public boolean matches(final String commandName) {
- return StringUtils.isNotEmpty(commandName)
- && compiledPattern.matcher(commandName).matches();
+ return StringUtils.isNotEmpty(commandName) &&
+ matchingPattern.matcher(commandName.toLowerCase()).matches();
}
public String getRuleString() {
diff --git a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
index 82a8ec5fe932..fa17df7c6ed4 100644
--- a/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
+++ b/api/src/main/java/org/apache/cloudstack/acl/SecurityChecker.java
@@ -27,6 +27,8 @@
import com.cloud.user.User;
import com.cloud.utils.component.Adapter;
+import org.apache.cloudstack.backup.BackupOffering;
+
/**
* SecurityChecker checks the ownership and access control to objects within
*/
@@ -145,4 +147,6 @@ boolean checkAccess(Account caller, AccessType accessType, String action, Contro
boolean checkAccess(Account account, NetworkOffering nof, DataCenter zone) throws PermissionDeniedException;
boolean checkAccess(Account account, VpcOffering vof, DataCenter zone) throws PermissionDeniedException;
+
+ boolean checkAccess(Account account, BackupOffering bof) throws PermissionDeniedException;
}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java
new file mode 100644
index 000000000000..ecce0ae50824
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPair.java
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import java.util.Date;
+
+public interface ApiKeyPair extends ControlledEntity, InternalIdentity, Identity {
+ Long getUserId();
+ Date getStartDate();
+ Date getEndDate();
+ Date getCreated();
+ String getDescription();
+ String getApiKey();
+ String getSecretKey();
+ String getName();
+ Date getRemoved();
+ void setRemoved(Date date);
+ void validateDate();
+ boolean hasEndDatePassed();
+}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java
new file mode 100644
index 000000000000..60b3834cc073
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairPermission.java
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import org.apache.cloudstack.acl.RolePermissionEntity;
+
+public interface ApiKeyPairPermission extends RolePermissionEntity {
+ long getApiKeyPairId();
+}
diff --git a/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java
new file mode 100644
index 000000000000..de9c829b17dc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/acl/apikeypair/ApiKeyPairService.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.acl.apikeypair;
+
+import java.util.List;
+
+public interface ApiKeyPairService {
+ List findAllPermissionsByKeyPairId(Long apiKeyPairId, Long roleId);
+
+ ApiKeyPair findByApiKey(String apiKey);
+
+ ApiKeyPair findById(Long id);
+}
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
index 018e5f5bab5a..03992c0c1c7c 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityGroupService.java
@@ -66,5 +66,4 @@ public interface AffinityGroupService {
boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId);
-
}
diff --git a/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java b/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
index 9995d8039e1f..96ca35f264ca 100644
--- a/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
+++ b/api/src/main/java/org/apache/cloudstack/affinity/AffinityProcessorBase.java
@@ -29,6 +29,9 @@
public class AffinityProcessorBase extends AdapterBase implements AffinityGroupProcessor {
+ public static final String AFFINITY_TYPE_HOST = "host affinity";
+ public static final String AFFINITY_TYPE_HOST_ANTI = "host anti-affinity";
+
protected String _type;
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
index 14223227c344..a9c2abc11ce7 100644
--- a/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
+++ b/api/src/main/java/org/apache/cloudstack/alert/AlertService.java
@@ -24,18 +24,24 @@
public interface AlertService {
public static class AlertType {
- private static Set defaultAlertTypes = new HashSet();
+ private static final Set defaultAlertTypes = new HashSet<>();
private final String name;
private final short type;
+ private final boolean repetitionAllowed;
- private AlertType(short type, String name, boolean isDefault) {
+ private AlertType(short type, String name, boolean isDefault, boolean repetitionAllowed) {
this.name = name;
this.type = type;
+ this.repetitionAllowed = repetitionAllowed;
if (isDefault) {
defaultAlertTypes.add(this);
}
}
+ private AlertType(short type, String name, boolean isDefault) {
+ this(type, name, isDefault, false);
+ }
+
public static final AlertType ALERT_TYPE_MEMORY = new AlertType(Capacity.CAPACITY_TYPE_MEMORY, "ALERT.MEMORY", true);
public static final AlertType ALERT_TYPE_CPU = new AlertType(Capacity.CAPACITY_TYPE_CPU, "ALERT.CPU", true);
public static final AlertType ALERT_TYPE_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_STORAGE, "ALERT.STORAGE", true);
@@ -45,37 +51,41 @@ private AlertType(short type, String name, boolean isDefault) {
public static final AlertType ALERT_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET = new AlertType(Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_IPV6_SUBNET, "ALERT.NETWORK.IPV6SUBNET", true);
public static final AlertType ALERT_TYPE_PRIVATE_IP = new AlertType(Capacity.CAPACITY_TYPE_PRIVATE_IP, "ALERT.NETWORK.PRIVATEIP", true);
public static final AlertType ALERT_TYPE_SECONDARY_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_SECONDARY_STORAGE, "ALERT.STORAGE.SECONDARY", true);
- public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true);
- public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true);
- public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true);
- public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true);
+ public static final AlertType ALERT_TYPE_HOST = new AlertType((short)7, "ALERT.COMPUTE.HOST", true, true);
+ public static final AlertType ALERT_TYPE_USERVM = new AlertType((short)8, "ALERT.USERVM", true, true);
+ public static final AlertType ALERT_TYPE_DOMAIN_ROUTER = new AlertType((short)9, "ALERT.SERVICE.DOMAINROUTER", true, true);
+ public static final AlertType ALERT_TYPE_CONSOLE_PROXY = new AlertType((short)10, "ALERT.SERVICE.CONSOLEPROXY", true, true);
public static final AlertType ALERT_TYPE_ROUTING = new AlertType((short)11, "ALERT.NETWORK.ROUTING", true);
- public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true);
+ public static final AlertType ALERT_TYPE_STORAGE_MISC = new AlertType((short)12, "ALERT.STORAGE.MISC", true, true);
public static final AlertType ALERT_TYPE_USAGE_SERVER = new AlertType((short)13, "ALERT.USAGE", true);
- public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true);
+ public static final AlertType ALERT_TYPE_MANAGEMENT_NODE = new AlertType((short)14, "ALERT.MANAGEMENT", true, true);
public static final AlertType ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = new AlertType((short)15, "ALERT.NETWORK.DOMAINROUTERMIGRATE", true);
public static final AlertType ALERT_TYPE_CONSOLE_PROXY_MIGRATE = new AlertType((short)16, "ALERT.SERVICE.CONSOLEPROXYMIGRATE", true);
public static final AlertType ALERT_TYPE_USERVM_MIGRATE = new AlertType((short)17, "ALERT.USERVM.MIGRATE", true);
public static final AlertType ALERT_TYPE_VLAN = new AlertType((short)18, "ALERT.NETWORK.VLAN", true);
- public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true);
+ public static final AlertType ALERT_TYPE_SSVM = new AlertType((short)19, "ALERT.SERVICE.SSVM", true, true);
public static final AlertType ALERT_TYPE_USAGE_SERVER_RESULT = new AlertType((short)20, "ALERT.USAGE.RESULT", true);
public static final AlertType ALERT_TYPE_STORAGE_DELETE = new AlertType((short)21, "ALERT.STORAGE.DELETE", true);
public static final AlertType ALERT_TYPE_UPDATE_RESOURCE_COUNT = new AlertType((short)22, "ALERT.RESOURCE.COUNT", true);
public static final AlertType ALERT_TYPE_USAGE_SANITY_RESULT = new AlertType((short)23, "ALERT.USAGE.SANITY", true);
public static final AlertType ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = new AlertType((short)24, "ALERT.NETWORK.DIRECTPUBLICIP", true);
public static final AlertType ALERT_TYPE_LOCAL_STORAGE = new AlertType((short)25, "ALERT.STORAGE.LOCAL", true);
- public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true);
+ public static final AlertType ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = new AlertType((short)26, "ALERT.RESOURCE.EXCEED", true, true);
public static final AlertType ALERT_TYPE_SYNC = new AlertType((short)27, "ALERT.TYPE.SYNC", true);
- public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true);
- public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true);
- public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true);
- public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true);
+ public static final AlertType ALERT_TYPE_UPLOAD_FAILED = new AlertType((short)28, "ALERT.UPLOAD.FAILED", true, true);
+ public static final AlertType ALERT_TYPE_OOBM_AUTH_ERROR = new AlertType((short)29, "ALERT.OOBM.AUTHERROR", true, true);
+ public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true, true);
+ public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true, true);
public static final AlertType ALERT_TYPE_VM_SNAPSHOT = new AlertType((short)32, "ALERT.VM.SNAPSHOT", true);
public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)33, "ALERT.VR.PUBLIC.IFACE.MTU", true);
public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)34, "ALERT.VR.PRIVATE.IFACE.MTU", true);
- public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true);
+ public static final AlertType ALERT_TYPE_EXTENSION_PATH_NOT_READY = new AlertType((short)33, "ALERT.TYPE.EXTENSION.PATH.NOT.READY", true, true);
+ public static final AlertType ALERT_TYPE_VPN_GATEWAY_OBSOLETE_PARAMETERS = new AlertType((short)34, "ALERT.S2S.VPN.GATEWAY.OBSOLETE.PARAMETERS", true, true);
public static final AlertType ALERT_TYPE_BACKUP_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_BACKUP_STORAGE, "ALERT.STORAGE.BACKUP", true);
public static final AlertType ALERT_TYPE_OBJECT_STORAGE = new AlertType(Capacity.CAPACITY_TYPE_OBJECT_STORAGE, "ALERT.STORAGE.OBJECT", true);
+ public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_FAILED = new AlertType((short)35, "ALERT.BACKUP.VALIDATION.FAILED", true, true);
+ public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_UNABLE_TO_VALIDATE = new AlertType((short)36, "ALERT.BACKUP.VALIDATION.UNABLE.TO.VALIDATE", true, true);
+ public static final AlertType ALERT_TYPE_BACKUP_VALIDATION_CLEANUP_FAILED = new AlertType((short)37, "ALERT.BACKUP.VALIDATION.CLEANUP_FAILED", true, true);
public short getType() {
return type;
@@ -85,6 +95,10 @@ public String getName() {
return name;
}
+ public boolean isRepetitionAllowed() {
+ return repetitionAllowed;
+ }
+
private static AlertType getAlertType(short type) {
for (AlertType alertType : defaultAlertTypes) {
if (alertType.getType() == type) {
@@ -108,7 +122,7 @@ public static AlertType generateAlert(short type, String name) {
if (defaultAlert != null && !defaultAlert.getName().equalsIgnoreCase(name)) {
throw new InvalidParameterValueException("There is a default alert having type " + type + " and name " + defaultAlert.getName());
} else {
- return new AlertType(type, name, false);
+ return new AlertType(type, name, false, false);
}
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/APICommand.java b/api/src/main/java/org/apache/cloudstack/api/APICommand.java
index c559be081165..b77649046ca9 100644
--- a/api/src/main/java/org/apache/cloudstack/api/APICommand.java
+++ b/api/src/main/java/org/apache/cloudstack/api/APICommand.java
@@ -50,4 +50,6 @@
RoleType[] authorized() default {};
Class>[] entityType() default {};
+
+ String httpMethod() default "";
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
index e2ebb242cbf2..2aa97b65a3d5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java
@@ -89,7 +89,9 @@ public enum ApiCommandResourceType {
KubernetesSupportedVersion(null),
SharedFS(org.apache.cloudstack.storage.sharedfs.SharedFS.class),
Extension(org.apache.cloudstack.extension.Extension.class),
- ExtensionCustomAction(org.apache.cloudstack.extension.ExtensionCustomAction.class);
+ ExtensionCustomAction(org.apache.cloudstack.extension.ExtensionCustomAction.class),
+ KmsKey(org.apache.cloudstack.kms.KMSKey.class),
+ HsmProfile(org.apache.cloudstack.kms.HSMProfile.class);
private final Class> clazz;
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index a8ff00c40ff3..ac6acdf42516 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -19,6 +19,8 @@
public class ApiConstants {
public static final String ACCOUNT = "account";
public static final String ACCOUNTS = "accounts";
+ public static final String ACCOUNT_NAME = "accountname";
+ public static final String ACCOUNT_STATE_TO_SHOW = "accountstatetoshow";
public static final String ACCOUNT_TYPE = "accounttype";
public static final String ACCOUNT_ID = "accountid";
public static final String ACCOUNT_IDS = "accountids";
@@ -46,6 +48,7 @@ public class ApiConstants {
public static final String AS_NUMBER_ID = "asnumberid";
public static final String ASN_RANGE = "asnrange";
public static final String ASN_RANGE_ID = "asnrangeid";
+ public static final String API_KEY_FILTER = "apikeyfilter";
public static final String ASYNC_BACKUP = "asyncbackup";
public static final String AUTO_SELECT = "autoselect";
public static final String USER_API_KEY = "userapikey";
@@ -60,12 +63,15 @@ public class ApiConstants {
public static final String BACKUP_LIMIT = "backuplimit";
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
public static final String BACKUP_OFFERING_ID = "backupofferingid";
+ public static final String BACKUP_OFFERING_DETAILS = "backupofferingdetails";
public static final String BACKUP_STORAGE_AVAILABLE = "backupstorageavailable";
public static final String BACKUP_STORAGE_LIMIT = "backupstoragelimit";
public static final String BACKUP_STORAGE_TOTAL = "backupstoragetotal";
public static final String BACKUP_VM_OFFERING_REMOVED = "vmbackupofferingremoved";
public static final String IS_BACKUP_VM_EXPUNGED = "isbackupvmexpunged";
public static final String BACKUP_TOTAL = "backuptotal";
+ public static final String BALANCE = "balance";
+ public static final String BALANCES = "balances";
public static final String BASE64_IMAGE = "base64image";
public static final String BGP_PEERS = "bgppeers";
public static final String BGP_PEER_IDS = "bgppeerids";
@@ -74,6 +80,7 @@ public class ApiConstants {
public static final String BOOTABLE = "bootable";
public static final String BIND_DN = "binddn";
public static final String BIND_PASSWORD = "bindpass";
+ public static final String BLANK_INSTANCE = "blankinstance";
public static final String BUS_ADDRESS = "busaddress";
public static final String BYTES_READ_RATE = "bytesreadrate";
public static final String BYTES_READ_RATE_MAX = "bytesreadratemax";
@@ -154,6 +161,7 @@ public class ApiConstants {
public static final String CUSTOM_ID = "customid";
public static final String CUSTOM_ACTION_ID = "customactionid";
public static final String CUSTOM_JOB_ID = "customjobid";
+ public static final String CURRENCY = "currency";
public static final String CURRENT_START_IP = "currentstartip";
public static final String CURRENT_END_IP = "currentendip";
public static final String ENCRYPT = "encrypt";
@@ -167,6 +175,7 @@ public class ApiConstants {
public static final String DATACENTER_NAME = "datacentername";
public static final String DATADISKS_DETAILS = "datadisksdetails";
public static final String DATADISK_OFFERING_LIST = "datadiskofferinglist";
+ public static final String DATE = "date";
public static final String DEFAULT_VALUE = "defaultvalue";
public static final String DELETE_PROTECTION = "deleteprotection";
public static final String DESCRIPTION = "description";
@@ -194,6 +203,7 @@ public class ApiConstants {
public static final String UTILIZATION = "utilization";
public static final String DRIVER = "driver";
public static final String ROOT_DISK_SIZE = "rootdisksize";
+ public static final String ROOT_DISK_KMS_KEY_ID = "rootdiskkmskeyid";
public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
public static final String DHCP_OPTIONS = "dhcpoptions";
public static final String DHCP_PREFIX = "dhcp:";
@@ -213,6 +223,7 @@ public class ApiConstants {
public static final String DOMAIN_PATH = "domainpath";
public static final String DOMAIN_ID = "domainid";
public static final String DOMAIN__ID = "domainId";
+ public static final String DUMMY = "dummy";
public static final String DURATION = "duration";
public static final String ELIGIBLE = "eligible";
public static final String EMAIL = "email";
@@ -256,6 +267,7 @@ public class ApiConstants {
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
public static final String FOR_SYSTEM_VMS = "forsystemvms";
public static final String FOR_PROVIDER = "forprovider";
+ public static final String FROM_CHECKPOINT_ID = "fromcheckpointid";
public static final String FULL_PATH = "fullpath";
public static final String GATEWAY = "gateway";
public static final String IP6_GATEWAY = "ip6gateway";
@@ -275,6 +287,7 @@ public class ApiConstants {
public static final String HEALTH = "health";
public static final String HEADERS = "headers";
public static final String HIDE_IP_ADDRESS_USAGE = "hideipaddressusage";
+ public static final String HISTORY = "history";
public static final String HOST_ID = "hostid";
public static final String HOST_IDS = "hostids";
public static final String HOST_IP = "hostip";
@@ -282,6 +295,7 @@ public class ApiConstants {
public static final String HOST = "host";
public static final String HOST_CONTROL_STATE = "hostcontrolstate";
public static final String HOSTS_MAP = "hostsmap";
+ public static final String HTTP_REQUEST_TYPE = "httprequesttype";
public static final String HYPERVISOR = "hypervisor";
public static final String INLINE = "inline";
public static final String INSTANCE = "instance";
@@ -327,6 +341,7 @@ public class ApiConstants {
public static final String IS_2FA_VERIFIED = "is2faverified";
public static final String IS_2FA_MANDATED = "is2famandated";
+ public static final String IS_ACTIVE = "isactive";
public static final String IS_ASYNC = "isasync";
public static final String IP_AVAILABLE = "ipavailable";
public static final String IP_LIMIT = "iplimit";
@@ -355,6 +370,7 @@ public class ApiConstants {
public static final String JOB_STATUS = "jobstatus";
public static final String KEEPALIVE_ENABLED = "keepaliveenabled";
public static final String KERNEL_VERSION = "kernelversion";
+ public static final String KEYPAIR_ID = "keypairid";
public static final String KEY = "key";
public static final String LABEL = "label";
public static final String LASTNAME = "lastname";
@@ -375,6 +391,7 @@ public class ApiConstants {
public static final String MAC_ADDRESS = "macaddress";
public static final String MAC_ADDRESSES = "macaddresses";
public static final String MANUAL_UPGRADE = "manualupgrade";
+ public static final String MATCH_TYPE = "matchtype";
public static final String MAX = "max";
public static final String MAX_SNAPS = "maxsnaps";
public static final String MAX_BACKUPS = "maxbackups";
@@ -435,6 +452,7 @@ public class ApiConstants {
public static final String MAX_VGPU_PER_PHYSICAL_GPU = "maxvgpuperphysicalgpu";
public static final String GUEST_OS_LIST = "guestoslist";
public static final String GUEST_OS_COUNT = "guestoscount";
+ public static final String GUEST_OS_RULE = "guestosrule";
public static final String OS_MAPPING_CHECK_ENABLED = "osmappingcheckenabled";
public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
@@ -501,6 +519,7 @@ public class ApiConstants {
public static final String RECONNECT = "reconnect";
public static final String RECOVER = "recover";
public static final String REPAIR = "repair";
+ public static final String REPETITION_ALLOWED = "repetitionallowed";
public static final String REQUIRES_HVM = "requireshvm";
public static final String RESERVED_RESOURCE_DETAILS = "reservedresourcedetails";
public static final String RESOURCES = "resources";
@@ -516,12 +535,12 @@ public class ApiConstants {
public static final String QUALIFIERS = "qualifiers";
public static final String QUERY_FILTER = "queryfilter";
public static final String QUIESCE_VM = "quiescevm";
+ public static final String QUICK_RESTORE = "quickrestore";
public static final String SCHEDULE = "schedule";
public static final String SCHEDULE_ID = "scheduleid";
public static final String SCOPE = "scope";
public static final String SEARCH_BASE = "searchbase";
public static final String SECONDARY_IP = "secondaryip";
- public static final String SECRET_KEY = "secretkey";
public static final String SECURITY_GROUP_IDS = "securitygroupids";
public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
public static final String SECURITY_GROUP_NAME = "securitygroupname";
@@ -535,9 +554,11 @@ public class ApiConstants {
public static final String SESSIONKEY = "sessionkey";
public static final String SHOW_CAPACITIES = "showcapacities";
public static final String SHOW_REMOVED = "showremoved";
+ public static final String SHOW_RESOURCES = "showresources";
public static final String SHOW_RESOURCE_ICON = "showicon";
public static final String SHOW_INACTIVE = "showinactive";
public static final String SHOW_UNIQUE = "showunique";
+ public static final String SHOW_PERMISSIONS = "showpermissions";
public static final String SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
public static final String SINCE = "since";
@@ -553,6 +574,7 @@ public class ApiConstants {
public static final String USE_STORAGE_REPLICATION = "usestoragereplication";
public static final String SOURCE_CIDR_LIST = "sourcecidrlist";
+ public static final String SOURCE_OFFERING_ID = "sourceofferingid";
public static final String SOURCE_ZONE_ID = "sourcezoneid";
public static final String SSL_VERIFICATION = "sslverification";
public static final String START_ASN = "startasn";
@@ -564,6 +586,8 @@ public class ApiConstants {
public static final String STATE = "state";
public static final String STATS = "stats";
public static final String STATUS = "status";
+ public static final String COMPRESSION_STATUS = "compressionstatus";
+ public static final String VALIDATION_STATUS = "validationstatus";
public static final String STORAGE_TYPE = "storagetype";
public static final String STORAGE_POLICY = "storagepolicy";
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
@@ -585,6 +609,8 @@ public class ApiConstants {
public static final String SUITABLE_FOR_VM = "suitableforvirtualmachine";
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
public static final String TARGET_IQN = "targetiqn";
+ public static final String TARIFF_ID = "tariffid";
+ public static final String TARIFF_NAME = "tariffname";
public static final String TASKS_FILTER = "tasksfilter";
public static final String TEMPLATE_FILTER = "templatefilter";
public static final String TEMPLATE_ID = "templateid";
@@ -598,9 +624,12 @@ public class ApiConstants {
public static final String TENANT_NAME = "tenantname";
public static final String TOTAL = "total";
public static final String TOTAL_SUBNETS = "totalsubnets";
+ public static final String TO_CHECKPOINT_ID = "tocheckpointid";
+ public static final String TOTAL_QUOTA = "totalquota";
public static final String TYPE = "type";
public static final String TRUST_STORE = "truststore";
public static final String TRUST_STORE_PASSWORD = "truststorepass";
+ public static final String UNIT = "unit";
public static final String URL = "url";
public static final String USAGE_INTERFACE = "usageinterface";
public static final String USED = "used";
@@ -643,6 +672,7 @@ public class ApiConstants {
public static final String VIRTUAL_MACHINE_STATE = "vmstate";
public static final String VIRTUAL_MACHINES = "virtualmachines";
public static final String USAGE_ID = "usageid";
+ public static final String USAGE_NAME = "usagename";
public static final String USAGE_TYPE = "usagetype";
public static final String INCLUDE_TAGS = "includetags";
@@ -656,6 +686,7 @@ public class ApiConstants {
public static final String ETCD_SERVICE_OFFERING_NAME = "etcdofferingname";
public static final String REMOVE_VLAN = "removevlan";
public static final String VLAN_ID = "vlanid";
+ public static final String ISOLATED = "isolated";
public static final String ISOLATED_PVLAN = "isolatedpvlan";
public static final String ISOLATED_PVLAN_TYPE = "isolatedpvlantype";
public static final String ISOLATION_URI = "isolationuri";
@@ -764,6 +795,7 @@ public class ApiConstants {
public static final String ROLE_TYPE = "roletype";
public static final String ROLE_NAME = "rolename";
public static final String PERMISSION = "permission";
+ public static final String PERMISSIONS = "permissions";
public static final String RULE = "rule";
public static final String RULES = "rules";
public static final String RULE_ID = "ruleid";
@@ -858,9 +890,17 @@ public class ApiConstants {
public static final String IS_SOURCE_NAT = "issourcenat";
public static final String IS_STATIC_NAT = "isstaticnat";
public static final String ITERATIONS = "iterations";
+ public static final String ITEMS = "items";
public static final String SORT_BY = "sortby";
public static final String CHANGE_CIDR = "changecidr";
+ public static final String HSM_PROFILE = "hsmprofile";
+ public static final String HSM_PROFILE_ID = "hsmprofileid";
public static final String PURPOSE = "purpose";
+ public static final String KMS_KEY = "kmskey";
+ public static final String KMS_KEY_ID = "kmskeyid";
+ public static final String KMS_KEY_VERSION = "kmskeyversion";
+ public static final String KEK_LABEL = "keklabel";
+ public static final String KEY_BITS = "keybits";
public static final String IS_TAGGED = "istagged";
public static final String INSTANCE_NAME = "instancename";
public static final String CONSIDER_LAST_HOST = "considerlasthost";
@@ -981,6 +1021,7 @@ public class ApiConstants {
public static final String REGION_ID = "regionid";
public static final String VPC_OFF_ID = "vpcofferingid";
public static final String VPC_OFF_NAME = "vpcofferingname";
+ public static final String VPC_OFFERING_CONSERVE_MODE = "vpcofferingconservemode";
public static final String NETWORK = "network";
public static final String VPC_ID = "vpcid";
public static final String VPC_NAME = "vpcname";
@@ -1027,7 +1068,7 @@ public class ApiConstants {
public static final String NSX_PROVIDER_PORT = "nsxproviderport";
public static final String NSX_CONTROLLER_ID = "nsxcontrollerid";
public static final String S3_ACCESS_KEY = "accesskey";
- public static final String S3_SECRET_KEY = "secretkey";
+ public static final String SECRET_KEY = "secretkey";
public static final String S3_END_POINT = "endpoint";
public static final String S3_BUCKET_NAME = "bucket";
public static final String S3_SIGNER = "s3signer";
@@ -1167,8 +1208,10 @@ public class ApiConstants {
public static final String OVM3_VIP = "ovm3vip";
public static final String CLEAN_UP_DETAILS = "cleanupdetails";
public static final String CLEAN_UP_EXTERNAL_DETAILS = "cleanupexternaldetails";
+ public static final String CLEAN_UP_EXTRA_CONFIG = "cleanupextraconfig";
public static final String CLEAN_UP_PARAMETERS = "cleanupparameters";
public static final String VIRTUAL_SIZE = "virtualsize";
+ public static final String UNCOMPRESSED_SIZE = "uncompressedsize";
public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid";
public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid";
public static final String FETCH_ROUTER_HEALTH_CHECK_RESULTS = "fetchhealthcheckresults";
@@ -1238,6 +1281,13 @@ public class ApiConstants {
public static final String MAX_SIZE = "maxsize";
public static final String NODE_TYPE_OFFERING_MAP = "nodeofferings";
public static final String NODE_TYPE_TEMPLATE_MAP = "nodetemplates";
+ public static final String NODE_TYPE_AFFINITY_GROUP_MAP = "nodeaffinitygroups";
+ public static final String CONTROL_AFFINITY_GROUP_IDS = "controlaffinitygroupids";
+ public static final String CONTROL_AFFINITY_GROUP_NAMES = "controlaffinitygroupnames";
+ public static final String WORKER_AFFINITY_GROUP_IDS = "workeraffinitygroupids";
+ public static final String WORKER_AFFINITY_GROUP_NAMES = "workeraffinitygroupnames";
+ public static final String ETCD_AFFINITY_GROUP_IDS = "etcdaffinitygroupids";
+ public static final String ETCD_AFFINITY_GROUP_NAMES = "etcdaffinitygroupnames";
public static final String BOOT_TYPE = "boottype";
public static final String BOOT_MODE = "bootmode";
@@ -1259,6 +1309,7 @@ public class ApiConstants {
public static final String PROVIDER_FOR_2FA = "providerfor2fa";
public static final String ISSUER_FOR_2FA = "issuerfor2fa";
public static final String MANDATE_2FA = "mandate2fa";
+ public static final String PASSWORD_CHANGE_REQUIRED = "passwordchangerequired";
public static final String SECRET_CODE = "secretcode";
public static final String LOGIN = "login";
public static final String LOGOUT = "logout";
@@ -1281,6 +1332,8 @@ public class ApiConstants {
public static final String OBJECT_LOCKING = "objectlocking";
public static final String ENCRYPTION = "encryption";
public static final String QUOTA = "quota";
+ public static final String QUOTA_CONSUMED = "quotaconsumed";
+ public static final String QUOTA_USAGE = "quotausage";
public static final String ACCESS_KEY = "accesskey";
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
@@ -1295,7 +1348,7 @@ public class ApiConstants {
public static final String IMPORT_SOURCE = "importsource";
public static final String TEMP_PATH = "temppath";
public static final String HEURISTIC_RULE = "heuristicrule";
- public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, TEMPLATE and VOLUME.";
+ public static final String HEURISTIC_TYPE_VALID_OPTIONS = "Valid options are: ISO, SNAPSHOT, BACKUP, TEMPLATE and VOLUME.";
public static final String MANAGEMENT = "management";
public static final String IS_VNF = "isvnf";
public static final String VNF_NICS = "vnfnics";
@@ -1305,8 +1358,10 @@ public class ApiConstants {
public static final String VNF_CONFIGURE_MANAGEMENT = "vnfconfiguremanagement";
public static final String VNF_CIDR_LIST = "vnfcidrlist";
+ public static final String AUTHORIZE_URL = "authorizeurl";
public static final String CLIENT_ID = "clientid";
public static final String REDIRECT_URI = "redirecturi";
+ public static final String TOKEN_URL = "tokenurl";
public static final String IS_TAG_A_RULE = "istagarule";
@@ -1331,6 +1386,45 @@ public class ApiConstants {
public static final String OBJECT_STORAGE_LIMIT = "objectstoragelimit";
public static final String OBJECT_STORAGE_TOTAL = "objectstoragetotal";
+ public static final String KEEP_MAC_ADDRESS_ON_PUBLIC_NIC = "keepmacaddressonpublicnic";
+
+ public static final String PARAMETER_DESCRIPTION_KEEP_MAC_ADDRESS_ON_PUBLIC_NIC =
+ "Indicates whether to use the same MAC address for the public NIC of VRs on the same network. If \"true\", when creating redundant routers or recreating" +
+ " a VR, CloudStack will use the same MAC address for the public NIC of all VRs. Otherwise, if \"false\", new public NICs will always have " +
+ " a new MAC address.";
+
+ // DNS provider related
+ public static final String NAME_SERVERS = "nameservers";
+ public static final String DNS_USER_NAME = "dnsusername";
+ public static final String DNS_API_KEY = "dnsapikey";
+ public static final String DNS_ZONE_ID = "dnszoneid";
+ public static final String DNS_ZONE = "dnszone";
+ public static final String DNS_RECORD = "dnsrecord";
+ public static final String DNS_SUB_DOMAIN = "dnssubdomain";
+ public static final String DNS_SERVER_ID = "dnsserverid";
+ public static final String CONTENT = "content";
+ public static final String CONTENTS = "contents";
+ public static final String PUBLIC_DOMAIN_SUFFIX = "publicdomainsuffix";
+ public static final String AUTHORITATIVE = "authoritative";
+ public static final String KIND = "kind";
+ public static final String DNS_SEC = "dnssec";
+ public static final String TTL = "ttl";
+ public static final String CHANGE_TYPE = "changetype";
+ public static final String RECORDS = "records";
+ public static final String RR_SETS = "rrsets";
+ public static final String X_API_KEY = "X-API-Key";
+ public static final String DISABLED = "disabled";
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String NATIVE_ZONE = "Native";
+ public static final String NIC_DNS_NAME = "nicdnsname";
+ public static final String TIME_STAMP = "timestamp";
+ public static final String INSTANCE_ID = "instanceId";
+ public static final String OLD_STATE = "oldState";
+ public static final String NEW_STATE = "newState";
+ public static final String OLD_HOST_NAME = "oldHostName";
+ public static final String EXISTING = "existing";
+ public static final String UNMANAGE = "unmanage";
+
public static final String PARAMETER_DESCRIPTION_ACTIVATION_RULE = "Quota tariff's activation rule. It can receive a JS script that results in either " +
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
@@ -1350,9 +1444,14 @@ public class ApiConstants {
public static final String VMWARE_DC = "vmwaredc";
+ public static final String PARAMETER_DESCRIPTION_ISOLATED_BACKUPS = "Whether the backup will be isolated, defaults to false. " +
+ "Isolated backups are always created as full backups in independent chains. Therefore, they will never depend on any existing backup chain " +
+ "and no backup chain will depend on them. Currently only supported for the KBOSS provider.";
+
public static final String CSS = "css";
public static final String JSON_CONFIGURATION = "jsonconfiguration";
+ public static final String LOGIN_BASE_DOMAIN = "loginbasedomain";
public static final String COMMON_NAMES = "commonnames";
@@ -1366,6 +1465,31 @@ public class ApiConstants {
public static final String RECURSIVE_DOMAINS = "recursivedomains";
+ public static final String VPN_CUSTOMER_GATEWAY_PARAMETERS = "vpncustomergatewayparameters";
+ public static final String OBSOLETE_PARAMETERS = "obsoleteparameters";
+ public static final String EXCLUDED_PARAMETERS = "excludedparameters";
+
+ public static final String COMPRESS = "compress";
+
+ public static final String VALIDATE = "validate";
+
+ public static final String VALIDATION_STEPS = "validationsteps";
+
+ public static final String ALLOW_QUICK_RESTORE = "allowquickrestore";
+
+ public static final String ALLOW_EXTRACT_FILE = "allowextractfile";
+
+ public static final String BACKUP_CHAIN_SIZE = "backupchainsize";
+
+ public static final String COMPRESSION_LIBRARY = "compressionlibrary";
+ public static final String ATTEMPTS = "attempts";
+
+ public static final String EXECUTING = "executing";
+
+ public static final String SCHEDULED = "scheduled";
+ public static final String SCHEDULED_DATE = "scheduleddate";
+ public static final String BACKUP_PROVIDER = "backupprovider";
+
/**
* This enum specifies IO Drivers, each option controls specific policies on I/O.
* Qemu guests support "threads" and "native" options Since 0.8.8 ; "io_uring" is supported Since 6.3.0 (QEMU 5.0).
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
index 18c96c371591..1ee41ac86c22 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiServerService.java
@@ -21,8 +21,11 @@
import javax.servlet.http.HttpSession;
+import org.apache.cloudstack.context.CallContext;
+
import com.cloud.domain.Domain;
import com.cloud.exception.CloudAuthenticationException;
+import com.cloud.user.Account;
import com.cloud.user.UserAccount;
public interface ApiServerService {
@@ -52,4 +55,20 @@ public ResponseObject loginUser(HttpSession session, String username, String pas
String getDomainId(Map params);
boolean isPostRequestsAndTimestampsEnforced();
+
+ AsyncCmdResult processAsyncCmd(BaseAsyncCmd cmdObj, Map params, CallContext ctx, Long callerUserId, Account caller) throws Exception;
+
+ class AsyncCmdResult {
+ public final Long objectId;
+ public final String objectUuid;
+ public final BaseAsyncCmd asyncCmd;
+ public final long jobId;
+
+ public AsyncCmdResult(Long objectId, String objectUuid, BaseAsyncCmd asyncCmd, long jobId) {
+ this.objectId = objectId;
+ this.objectUuid = objectUuid;
+ this.asyncCmd = asyncCmd;
+ this.jobId = jobId;
+ }
+ }
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
index 6859b0a7f406..c67c5a023e09 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCmd.java
@@ -29,6 +29,7 @@ public abstract class BaseAsyncCmd extends BaseCmd {
public static final String migrationSyncObject = "migration";
public static final String snapshotHostSyncObject = "snapshothost";
public static final String gslbSyncObject = "globalserverloadbalancer";
+ public static final String user = "user";
private Object job;
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
index 30baa71d6d85..b9b13dcfd884 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseAsyncCreateCustomIdCmd.java
@@ -20,7 +20,7 @@ public abstract class BaseAsyncCreateCustomIdCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.CUSTOM_ID,
type = CommandType.STRING,
description = "An optional field, in case you want to set a custom id to the resource. Allowed to Root Admins only")
- private String customId;
+ protected String customId;
public String getCustomId() {
return customId;
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
index 0aa8366bcd5c..2a64a1fb6fd8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseBackupListCmd.java
@@ -25,7 +25,7 @@
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.context.CallContext;
-public abstract class BaseBackupListCmd extends BaseListCmd {
+public abstract class BaseBackupListCmd extends BaseListAccountResourcesCmd {
protected void setupResponseBackupOfferingsList(final List offerings, final Integer count) {
final ListResponse response = new ListResponse<>();
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
index 8f47d51b19d4..483fa83630ad 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseCmd.java
@@ -35,10 +35,12 @@
import org.apache.cloudstack.acl.ProjectRoleService;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairService;
import org.apache.cloudstack.affinity.AffinityGroupService;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.dns.DnsProviderManager;
import org.apache.cloudstack.gpu.GpuService;
import org.apache.cloudstack.network.RoutedIpv4Manager;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
@@ -220,6 +222,8 @@ public static enum CommandType {
@Inject
public Ipv6Service ipv6Service;
@Inject
+ public ApiKeyPairService apiKeyPairService;
+ @Inject
public VnfTemplateManager vnfTemplateManager;
@Inject
public BucketApiService _bucketService;
@@ -229,6 +233,9 @@ public static enum CommandType {
@Inject
public RoutedIpv4Manager routedIpv4Manager;
+ @Inject
+ public DnsProviderManager dnsProviderManager;
+
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException, NetworkRuleConflictException;
@@ -382,7 +389,7 @@ public List getParamFields() {
if (roleIsAllowed) {
validFields.add(field);
} else {
- logger.debug("Ignoring parameter " + parameterAnnotation.name() + " as the caller is not authorized to pass it in");
+ logger.debug("Ignoring parameter {} as the caller is not authorized to pass it in", parameterAnnotation.name());
}
}
@@ -498,4 +505,8 @@ public Map convertExternalDetailsToMap(Map externalDetails) {
}
return details;
}
+
+ public String getResourceUuid(String parameterName) {
+ return CallContext.current().getApiResourceUuid(parameterName);
+ }
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
index 087bf21784c1..94c5d8ff39fc 100644
--- a/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/BaseUpdateTemplateOrIsoCmd.java
@@ -84,7 +84,7 @@ public abstract class BaseUpdateTemplateOrIsoCmd extends BaseCmd {
private Boolean cleanupDetails;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the template/ISO. Valid options are: x86_64, aarch64",
+ description = "the CPU arch of the template/ISO. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
diff --git a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
index 8e92e877f5ca..6e880c89432f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java
@@ -24,6 +24,8 @@
import org.apache.cloudstack.api.response.ConsoleSessionResponse;
import org.apache.cloudstack.consoleproxy.ConsoleSession;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
+import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
@@ -41,6 +43,7 @@
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.api.response.BackupRepositoryResponse;
import org.apache.cloudstack.api.response.BackupScheduleResponse;
+import org.apache.cloudstack.api.response.BaseRolePermissionResponse;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
@@ -77,6 +80,7 @@
import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.IsolationMethodResponse;
+import org.apache.cloudstack.api.response.ApiKeyPairResponse;
import org.apache.cloudstack.api.response.LBHealthCheckResponse;
import org.apache.cloudstack.api.response.LBStickinessResponse;
import org.apache.cloudstack.api.response.ListResponse;
@@ -277,7 +281,8 @@ public interface ResponseGenerator {
List createUserVmResponse(ResponseView view, String objectName, UserVm... userVms);
- List createUserVmResponse(ResponseView view, String objectName, EnumSet details, UserVm... userVms);
+ List createUserVmResponse(ResponseView view, String objectName, EnumSet details,
+ UserVm... userVms);
SystemVmResponse createSystemVmResponse(VirtualMachine systemVM);
@@ -303,11 +308,13 @@ public interface ResponseGenerator {
LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer);
- LBStickinessResponse createLBStickinessPolicyResponse(List extends StickinessPolicy> stickinessPolicies, LoadBalancer lb);
+ LBStickinessResponse createLBStickinessPolicyResponse(List extends StickinessPolicy> stickinessPolicies,
+ LoadBalancer lb);
LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb);
- LBHealthCheckResponse createLBHealthCheckPolicyResponse(List extends HealthCheckPolicy> healthcheckPolicies, LoadBalancer lb);
+ LBHealthCheckResponse createLBHealthCheckPolicyResponse(List extends HealthCheckPolicy> healthcheckPolicies,
+ LoadBalancer lb);
LBHealthCheckResponse createLBHealthCheckPolicyResponse(HealthCheckPolicy healthcheckPolicy, LoadBalancer lb);
@@ -315,7 +322,8 @@ public interface ResponseGenerator {
PodResponse createMinimalPodResponse(Pod pod);
- ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities, Boolean showResourceIcon);
+ ZoneResponse createZoneResponse(ResponseView view, DataCenter dataCenter, Boolean showCapacities,
+ Boolean showResourceIcon);
DataCenterGuestIpv6PrefixResponse createDataCenterGuestIpv6PrefixResponse(DataCenterGuestIpv6Prefix prefix);
@@ -339,6 +347,8 @@ public interface ResponseGenerator {
UserVm findUserVmById(Long vmId);
+ UserVm findUserVmByNicId(Long nicId);
+
Volume findVolumeById(Long volumeId);
Account findAccountByNameDomain(String accountName, Long domainId);
@@ -355,7 +365,8 @@ public interface ResponseGenerator {
List createTemplateResponses(ResponseView view, long templateId, Long zoneId, boolean readyOnly);
- List createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId, boolean readyOnly);
+ List createTemplateResponses(ResponseView view, long templateId, Long snapshotId, Long volumeId,
+ boolean readyOnly);
SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List extends SecurityRule> securityRules);
@@ -374,14 +385,15 @@ public interface ResponseGenerator {
TemplateResponse createTemplateUpdateResponse(ResponseView view, VirtualMachineTemplate result);
List createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
- Long zoneId, boolean readyOnly);
+ Long zoneId, boolean readyOnly);
List createTemplateResponses(ResponseView view, VirtualMachineTemplate result,
- List zoneIds, boolean readyOnly);
+ List zoneIds, boolean readyOnly);
List createCapacityResponse(List extends Capacity> result, DecimalFormat format);
- TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List accountNames, Long id);
+ TemplatePermissionsResponse createTemplatePermissionsResponse(ResponseView view, List accountNames,
+ Long id);
AsyncJobResponse queryJobResult(QueryAsyncJobResultCmd cmd);
@@ -395,7 +407,8 @@ List createTemplateResponses(ResponseView view, VirtualMachine
Long getSecurityGroupId(String groupName, long accountId);
- List createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId, boolean readyOnly);
+ List createIsoResponses(ResponseView view, VirtualMachineTemplate iso, Long zoneId,
+ boolean readyOnly);
ProjectResponse createProjectResponse(Project project);
@@ -496,13 +509,15 @@ List createTemplateResponses(ResponseView view, VirtualMachine
GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
- HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(List> hypervisorGuestOsNames);
+ HypervisorGuestOsNamesResponse createHypervisorGuestOSNamesResponse(
+ List> hypervisorGuestOsNames);
SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
UsageRecordResponse createUsageResponse(Usage usageRecord);
- UsageRecordResponse createUsageResponse(Usage usageRecord, Map> resourceTagResponseMap, boolean oldFormat);
+ UsageRecordResponse createUsageResponse(Usage usageRecord,
+ Map> resourceTagResponseMap, boolean oldFormat);
public Map> getUsageResourceTags();
@@ -514,7 +529,8 @@ List createTemplateResponses(ResponseView view, VirtualMachine
public NicResponse createNicResponse(Nic result);
- ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map lbInstances);
+ ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb,
+ Map lbInstances);
AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);
@@ -540,9 +556,12 @@ List createTemplateResponses(ResponseView view, VirtualMachine
ManagementServerResponse createManagementResponse(ManagementServerHost mgmt);
- List createHealthCheckResponse(VirtualMachine router, List healthCheckResults);
+ List createHealthCheckResponse(VirtualMachine router,
+ List healthCheckResults);
- RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details, List hostsUpdated, List hostsSkipped);
+ RollingMaintenanceResponse createRollingMaintenanceResponse(Boolean success, String details,
+ List hostsUpdated,
+ List hostsSkipped);
ResourceIconResponse createResourceIconResponse(ResourceIcon resourceIcon);
@@ -552,11 +571,14 @@ List createTemplateResponses(ResponseView view, VirtualMachine
DirectDownloadCertificateResponse createDirectDownloadCertificateResponse(DirectDownloadCertificate certificate);
- List createDirectDownloadCertificateHostMapResponse(List hostMappings);
+ List createDirectDownloadCertificateHostMapResponse(
+ List hostMappings);
- DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(DirectDownloadManager.HostCertificateStatus status);
+ DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateHostStatusResponse(
+ DirectDownloadManager.HostCertificateStatus status);
- DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair result);
+ DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId,
+ Long hostId, Pair result);
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
@@ -583,4 +605,8 @@ List createTemplateResponses(ResponseView view, VirtualMachine
GuiThemeResponse createGuiThemeResponse(GuiThemeJoin guiThemeJoin);
ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consoleSession, ResponseView responseView);
+
+ ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair);
+
+ ListResponse createKeypairPermissionsResponse(List permissions);
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
index ea25c56ee39e..cc154ed964b3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/CreateAccountCmd.java
@@ -177,7 +177,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
validateParams();
- CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain Id:" + getDomainId());
+ CallContext.current().setEventDetails("Account Name: " + getUsername() + ", Domain ID:" + getResourceUuid(ApiConstants.DOMAIN_ID));
UserAccount userAccount =
_accountService.createUserAccount(this);
if (userAccount != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
index 29774e254aa0..f7f8bd974272 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/account/DisableAccountCmd.java
@@ -108,12 +108,20 @@ public long getEntityOwnerId() {
@Override
public String getEventDescription() {
- return "Disabling Account: " + getAccountName() + " in domain: " + getDomainId();
+ String message = "Disabling Account ";
+
+ if (getId() != null) {
+ message += "with ID: " + getResourceUuid(ApiConstants.ID);
+ } else {
+ message += getAccountName() + " in Domain: " + getResourceUuid(ApiConstants.DOMAIN_ID);
+ }
+
+ return message;
}
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
- CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getDomainId());
+ CallContext.current().setEventDetails("Account Name: " + getAccountName() + ", Domain Id:" + getResourceUuid(ApiConstants.DOMAIN_ID));
Account result = _regionService.disableAccount(this);
if (result != null){
AccountResponse response = _responseGenerator.createAccountResponse(ResponseView.Full, result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
index 232c4760e1e6..13405431f63e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/CreateRolePermissionCmd.java
@@ -81,7 +81,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided");
}
- CallContext.current().setEventDetails("Role id: " + role.getId() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid() + ", rule:" + getRule() + ", permission: " + getPermission() + ", description: " + getDescription());
final RolePermission rolePermission = roleService.createRolePermission(role, getRule(), getPermission(), getDescription());
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create role permission");
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
index fd2d11aeda0a..80ec08260ab2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRoleCmd.java
@@ -70,7 +70,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.deleteRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
index bedaca9e23af..cf4a62bf6c43 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DeleteRolePermissionCmd.java
@@ -68,7 +68,7 @@ public void execute() {
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided");
}
- CallContext.current().setEventDetails("Role permission id: " + rolePermission.getId());
+ CallContext.current().setEventDetails("Role permission ID: " + rolePermission.getUuid());
boolean result = roleService.deleteRolePermission(rolePermission);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
index 80cb92c8362f..2c5659b2bc4b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/DisableRoleCmd.java
@@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.disableRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
index c4a6505d52f6..05dfbe1270fa 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/EnableRoleCmd.java
@@ -55,7 +55,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
}
- CallContext.current().setEventDetails("Role id: " + role.getId());
+ CallContext.current().setEventDetails("Role ID: " + role.getUuid());
boolean result = roleService.enableRole(role);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
index 8f8115e9957e..992564413f6b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/UpdateRolePermissionCmd.java
@@ -111,7 +111,7 @@ public void execute() {
if (getRuleId() != null || getRulePermission() != null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
- CallContext.current().setEventDetails("Reordering permissions for role id: " + role.getId());
+ CallContext.current().setEventDetails("Reordering permissions for role with ID: " + role.getUuid());
final List rolePermissionsOrder = new ArrayList<>();
for (Long rolePermissionId : getRulePermissionOrder()) {
final RolePermission rolePermission = roleService.findRolePermission(rolePermissionId);
@@ -129,7 +129,7 @@ public void execute() {
if (rolePermission == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid rule id provided");
}
- CallContext.current().setEventDetails("Updating permission for rule id: " + getRuleId() + " to: " + getRulePermission().toString());
+ CallContext.current().setEventDetails("Updating permission for rule with ID: " + getResourceUuid(ApiConstants.RULE_ID) + " to: " + getRulePermission().toString());
result = roleService.updateRolePermission(role, rolePermission, getRulePermission());
}
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
index d39c2312aa91..e085c10cee0b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/CreateProjectRolePermissionCmd.java
@@ -72,7 +72,7 @@ public void execute() {
if (projectRole == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid project role ID provided");
}
- CallContext.current().setEventDetails("Project Role ID: " + projectRole.getId() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription());
+ CallContext.current().setEventDetails("Project Role ID: " + projectRole.getUuid() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription());
final ProjectRolePermission projectRolePermission = projRoleService.createProjectRolePermission(this);
if (projectRolePermission == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create project role permission");
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
index 9f8d82489584..84f73e7a1a32 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRoleCmd.java
@@ -69,7 +69,7 @@ public void execute() {
if (role == null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find project role with provided id");
}
- CallContext.current().setEventDetails("Deleting Project Role with id: " + role.getId());
+ CallContext.current().setEventDetails("Deleting Project Role with ID: " + role.getUuid());
boolean result = projRoleService.deleteProjectRole(role, getProjectId());
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
index ac68278535e2..d7941a6a4cc3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/DeleteProjectRolePermissionCmd.java
@@ -70,7 +70,7 @@ public void execute() {
if (rolePermission == null || rolePermission.getProjectId() != getProjectId()) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided for the project");
}
- CallContext.current().setEventDetails("Deleting Project Role permission with id: " + rolePermission.getId());
+ CallContext.current().setEventDetails("Deleting Project Role permission with ID: " + rolePermission.getUuid());
boolean result = projRoleService.deleteProjectRolePermission(rolePermission);
SuccessResponse response = new SuccessResponse();
response.setSuccess(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
index b273b9f58493..fd0c043f2321 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/acl/project/UpdateProjectRolePermissionCmd.java
@@ -115,7 +115,7 @@ public void execute() {
if (getProjectRuleId() != null || getProjectRolePermission() != null) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
- CallContext.current().setEventDetails("Reordering permissions for role id: " + projectRole.getId());
+ CallContext.current().setEventDetails("Reordering permissions for role with ID: " + projectRole.getUuid());
result = updateProjectRolePermissionOrder(projectRole);
} else if (getProjectRuleId() != null || getProjectRolePermission() != null ) {
@@ -123,7 +123,7 @@ public void execute() {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
}
ProjectRolePermission rolePermission = getValidProjectRolePermission();
- CallContext.current().setEventDetails("Updating project role permission for rule id: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString());
+ CallContext.current().setEventDetails("Updating project role permission for rule ID: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString());
result = projRoleService.updateProjectRolePermission(projectId, projectRole, rolePermission, getProjectRolePermission());
}
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
index 0798357b8bcb..d7be56bf3f46 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/CreateCounterCmd.java
@@ -97,7 +97,7 @@ public void create() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Counter ID: " + getEntityId());
+ CallContext.current().setEventDetails("Counter ID: " + getEntityUuid());
Counter ctr = _autoScaleService.getCounter(getEntityId());
CounterResponse response = _responseGenerator.createCounterResponse(ctr);
response.setResponseName(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
index fb0c9606c512..8e941965e84b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/autoscale/DeleteCounterCmd.java
@@ -61,7 +61,7 @@ public void execute() {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
- logger.warn("Failed to delete counter with Id: " + getId());
+ logger.warn("Failed to delete counter with Id: {}", getId());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete counter.");
}
}
@@ -91,6 +91,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting a counter.";
+ return "Deleting auto scaling counter with ID: " + getResourceUuid(ApiConstants.ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java
new file mode 100644
index 000000000000..500a77f3d4fc
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CloneBackupOfferingCmd.java
@@ -0,0 +1,166 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
+import org.apache.cloudstack.api.response.BackupOfferingResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.BackupOffering;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.LongFunction;
+
+@APICommand(name = "cloneBackupOffering",
+ description = "Clones a backup offering from an existing offering",
+ responseObject = BackupOfferingResponse.class, since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class CloneBackupOfferingCmd extends BaseAsyncCmd implements DomainAndZoneIdResolver {
+
+ @Inject
+ protected BackupManager backupManager;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ ////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID, type = BaseCmd.CommandType.UUID, entityType = BackupOfferingResponse.class,
+ required = true, description = "The ID of the source backup offering to clone from")
+ private Long sourceOfferingId;
+
+ @Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
+ description = "The name of the cloned offering")
+ private String name;
+
+ @Parameter(name = ApiConstants.DESCRIPTION, type = BaseCmd.CommandType.STRING, required = false,
+ description = "The description of the cloned offering")
+ private String description;
+
+ @Parameter(name = ApiConstants.EXTERNAL_ID, type = BaseCmd.CommandType.STRING, required = false,
+ description = "The backup offering ID (from backup provider side)")
+ private String externalId;
+
+ @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
+ description = "The zone ID", required = false)
+ private Long zoneId;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.STRING,
+ description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ length = 4096)
+ private String domainIds;
+
+ @Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = BaseCmd.CommandType.BOOLEAN,
+ description = "Whether users are allowed to create adhoc backups and backup schedules", required = false)
+ private Boolean userDrivenBackups;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getExternalId() {
+ return externalId;
+ }
+
+ public Long getZoneId() {
+ return zoneId;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public Boolean getUserDrivenBackups() {
+ return userDrivenBackups;
+ }
+
+ public List getDomainIds() {
+ if (domainIds != null && !domainIds.isEmpty()) {
+ return Arrays.asList(Arrays.stream(domainIds.split(",")).map(domainId -> Long.parseLong(domainId.trim())).toArray(Long[]::new));
+ }
+ LongFunction> defaultDomainsProvider = null;
+ if (backupManager != null) {
+ defaultDomainsProvider = backupManager::getBackupOfferingDomains;
+ }
+ return resolveDomainIds(domainIds, sourceOfferingId, defaultDomainsProvider, "backup offering");
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ BackupOffering policy = backupManager.cloneBackupOffering(this);
+ if (policy == null) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone backup offering");
+ }
+ BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(policy);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (InvalidParameterValueException e) {
+ throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+ } catch (CloudRuntimeException e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_OFFERING_CLONE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Cloning backup offering: " + name + " from source offering: " + (sourceOfferingId == null ? "" : sourceOfferingId.toString());
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java
new file mode 100644
index 000000000000..c98bfb850529
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateImageTransferCmd.java
@@ -0,0 +1,100 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.utils.EnumUtils;
+
+@APICommand(name = "createImageTransfer",
+ description = "Create image transfer for a disk in backup. This API is intended for testing only and is disabled by default.",
+ responseObject = ImageTransferResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class CreateImageTransferCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.BACKUP_ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ description = "ID of the backup")
+ private Long backupId;
+
+ @Parameter(name = ApiConstants.VOLUME_ID,
+ type = CommandType.UUID,
+ entityType = VolumeResponse.class,
+ required = true,
+ description = "ID of the disk/volume")
+ private Long volumeId;
+
+ @Parameter(name = ApiConstants.DIRECTION,
+ type = CommandType.STRING,
+ required = true,
+ description = "Direction of the transfer: upload, download")
+ private String direction;
+
+ @Parameter(name = ApiConstants.FORMAT,
+ type = CommandType.STRING,
+ description = "Format for the image transfer: raw/cow. 'raw' will create an NBD backend. 'cow' will use the File backend." +
+ "For download, only the 'raw' format is supported. Default: raw")
+ private String format;
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ public Long getVolumeId() {
+ return volumeId;
+ }
+
+ public ImageTransfer.Direction getDirection() {
+ return ImageTransfer.Direction.valueOf(direction);
+ }
+
+ public ImageTransfer.Format getFormat() {
+ return EnumUtils.getEnum(ImageTransfer.Format.class, format);
+ }
+
+ @Override
+ public void execute() {
+ ImageTransferResponse response = kvmBackupExportService.createImageTransfer(this);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java
new file mode 100644
index 000000000000..d0e17e86d427
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteVmCheckpointCmd.java
@@ -0,0 +1,85 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "deleteVirtualMachineCheckpoint",
+ description = "Delete a VM checkpoint. This API is intended for testing only and is disabled by default.",
+ responseObject = SuccessResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class DeleteVmCheckpointCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = "checkpointid",
+ type = CommandType.STRING,
+ required = true,
+ description = "Checkpoint ID")
+ private String checkpointId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public String getCheckpointId() {
+ return checkpointId;
+ }
+
+ public void setVmId(Long vmId) {
+ this.vmId = vmId;
+ }
+
+ public void setCheckpointId(String checkpointId) {
+ this.checkpointId = checkpointId;
+ }
+
+ @Override
+ public void execute() {
+ boolean result = kvmBackupExportService.deleteVmCheckpoint(this);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java
new file mode 100644
index 000000000000..45173f8668ee
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeBackupCmd.java
@@ -0,0 +1,103 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.Backup;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+
+@APICommand(name = "finalizeBackup",
+ description = "Finalize a VM backup session. This API is intended for testing only and is disabled by default.",
+ responseObject = BackupResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class FinalizeBackupCmd extends BaseAsyncCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Inject
+ private BackupManager backupManager;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ required = true,
+ description = "ID of the backup")
+ private Long backupId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ @Override
+ public void execute() {
+ Backup backup = kvmBackupExportService.finalizeBackup(this);
+
+ if (backup == null) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Backup");
+ }
+
+ BackupResponse response = backupManager.createBackupResponse(backup, null);
+
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Finalizing backup " + backupId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java
new file mode 100644
index 000000000000..dfc43e233bf2
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/FinalizeImageTransferCmd.java
@@ -0,0 +1,69 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "finalizeImageTransfer",
+ description = "Finalize an image transfer. This API is intended for testing only and is disabled by default.",
+ responseObject = SuccessResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class FinalizeImageTransferCmd extends BaseCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = ImageTransferResponse.class,
+ required = true,
+ description = "ID of the image transfer")
+ private Long imageTransferId;
+
+ public Long getImageTransferId() {
+ return imageTransferId;
+ }
+
+ @Override
+ public void execute() {
+ boolean result = kvmBackupExportService.finalizeImageTransfer(this);
+ SuccessResponse response = new SuccessResponse(getCommandName());
+ response.setSuccess(result);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
index 2e73698e7aa1..4cf27c561508 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java
@@ -27,6 +27,7 @@
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.backup.BackupOffering;
@@ -40,6 +41,11 @@
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.commons.collections.CollectionUtils;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
@APICommand(name = "importBackupOffering",
description = "Imports a backup offering using a backup provider",
@@ -48,7 +54,7 @@
public class ImportBackupOfferingCmd extends BaseAsyncCmd {
@Inject
- private BackupManager backupManager;
+ protected BackupManager backupManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@@ -76,6 +82,14 @@ public class ImportBackupOfferingCmd extends BaseAsyncCmd {
description = "Whether users are allowed to create adhoc backups and backup schedules", required = true)
private Boolean userDrivenBackups;
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "the ID of the containing domain(s), null for public offerings",
+ since = "4.23.0")
+ private List domainIds;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -100,6 +114,15 @@ public Boolean getUserDrivenBackups() {
return userDrivenBackups == null ? false : userDrivenBackups;
}
+ public List getDomainIds() {
+ if (CollectionUtils.isNotEmpty(domainIds)) {
+ Set set = new LinkedHashSet<>(domainIds);
+ domainIds.clear();
+ domainIds.addAll(set);
+ }
+ return domainIds;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -134,6 +157,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone ID " + zoneId ;
+ return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID) ;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java
new file mode 100644
index 000000000000..d810d21ab5f8
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListImageTransfersCmd.java
@@ -0,0 +1,81 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.ImageTransferResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.backup.ImageTransfer;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = "listImageTransfers",
+ description = "List image transfers for a backup. This API is intended for testing only and is disabled by default.",
+ responseObject = ImageTransferResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class ListImageTransfersCmd extends BaseListCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.ID,
+ type = CommandType.UUID,
+ entityType = ImageTransferResponse.class,
+ description = "ID of the Image Transfer")
+ private Long id;
+
+ @Parameter(name = ApiConstants.BACKUP_ID,
+ type = CommandType.UUID,
+ entityType = BackupResponse.class,
+ description = "ID of the backup")
+ private Long backupId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getBackupId() {
+ return backupId;
+ }
+
+ @Override
+ public void execute() {
+ List responses = kvmBackupExportService.listImageTransfers(this);
+ ListResponse response = new ListResponse<>();
+ response.setResponses(responses);
+ response.setObjectName(ImageTransfer.class.getSimpleName().toLowerCase());
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java
new file mode 100644
index 000000000000..a61661e982de
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListVmCheckpointsCmd.java
@@ -0,0 +1,69 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.CheckpointResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+
+@APICommand(name = "listVirtualMachineCheckpoints",
+ description = "List checkpoints for a VM. This API is intended for testing only and is disabled by default.",
+ responseObject = CheckpointResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+public class ListVmCheckpointsCmd extends BaseListCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ @Override
+ public void execute() {
+ List responses = kvmBackupExportService.listVmCheckpoints(this);
+ ListResponse response = new ListResponse<>();
+ response.setResponses(responses);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return 0;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java
new file mode 100644
index 000000000000..1bf6d45db049
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/StartBackupCmd.java
@@ -0,0 +1,120 @@
+//Licensed to the Apache Software Foundation (ASF) under one
+//or more contributor license agreements. See the NOTICE file
+//distributed with this work for additional information
+//regarding copyright ownership. The ASF licenses this file
+//to you under the Apache License, Version 2.0 (the
+//"License"); you may not use this file except in compliance
+//the License. You may obtain a copy of the License at
+//
+//http://www.apache.org/licenses/LICENSE-2.0
+//
+//Unless required by applicable law or agreed to in writing,
+//software distributed under the License is distributed on an
+//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+//KIND, either express or implied. See the License for the
+//specific language governing permissions and limitations
+//under the License.
+
+package org.apache.cloudstack.api.command.admin.backup;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.admin.AdminCmd;
+import org.apache.cloudstack.api.response.BackupResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.backup.Backup;
+import org.apache.cloudstack.backup.BackupManager;
+import org.apache.cloudstack.backup.KVMBackupExportService;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+
+@APICommand(name = "startBackup",
+ description = "Start a VM backup session using pull mode backup-begin on the KVM host. This API is intended for testing only and is disabled by default.",
+ responseObject = BackupResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin})
+ public class StartBackupCmd extends BaseAsyncCreateCmd implements AdminCmd {
+
+ @Inject
+ private KVMBackupExportService kvmBackupExportService;
+
+ @Inject
+ private BackupManager backupManager;
+
+ @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
+ type = CommandType.UUID,
+ entityType = UserVmResponse.class,
+ required = true,
+ description = "ID of the VM")
+ private Long vmId;
+
+ @Parameter(name = ApiConstants.NAME,
+ type = CommandType.STRING,
+ description = "the name of the backup")
+ private String name;
+
+ @Parameter(name = ApiConstants.DESCRIPTION,
+ type = CommandType.STRING,
+ description = "the description for the backup")
+ private String description;
+
+ public Long getVmId() {
+ return vmId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public void execute() {
+ try {
+ Backup backup = kvmBackupExportService.startBackup(this);
+ BackupResponse response = backupManager.createBackupResponse(backup, null);
+
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } catch (Exception e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public void create() {
+ Backup backup = kvmBackupExportService.createBackup(this);
+
+ if (backup != null) {
+ setEntityId(backup.getId());
+ setEntityUuid(backup.getUuid());
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create Backup");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_VM_BACKUP_CREATE;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Starting backup for Instance " + vmId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
index 9de06715ee74..2f0dd6acd0e1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/UpdateBackupOfferingCmd.java
@@ -25,19 +25,24 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.backup.BackupOffering;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.user.Account;
import com.cloud.utils.exception.CloudRuntimeException;
+import java.util.List;
+import java.util.function.LongFunction;
+
@APICommand(name = "updateBackupOffering", description = "Updates a backup offering.", responseObject = BackupOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.16.0")
-public class UpdateBackupOfferingCmd extends BaseCmd {
+public class UpdateBackupOfferingCmd extends BaseCmd implements DomainAndZoneIdResolver {
@Inject
private BackupManager backupManager;
@@ -57,6 +62,13 @@ public class UpdateBackupOfferingCmd extends BaseCmd {
@Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = CommandType.BOOLEAN, description = "Whether to allow user driven backups or not")
private Boolean allowUserDrivenBackups;
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.STRING,
+ description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
+ since = "4.23.0",
+ length = 4096)
+ private String domainIds;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -82,7 +94,7 @@ public Boolean getAllowUserDrivenBackups() {
@Override
public void execute() {
try {
- if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null) {
+ if (StringUtils.isAllEmpty(getName(), getDescription()) && getAllowUserDrivenBackups() == null && CollectionUtils.isEmpty(getDomainIds())) {
throw new InvalidParameterValueException(String.format("Can't update Backup Offering [id: %s] because there are no parameters to be updated, at least one of the",
"following should be informed: name, description or allowUserDrivenBackups.", id));
}
@@ -98,11 +110,23 @@ public void execute() {
this.setResponseObject(response);
} catch (CloudRuntimeException e) {
ApiErrorCode paramError = e instanceof InvalidParameterValueException ? ApiErrorCode.PARAM_ERROR : ApiErrorCode.INTERNAL_ERROR;
- logger.error(String.format("Failed to update Backup Offering [id: %s] due to: [%s].", id, e.getMessage()), e);
+ logger.error("Failed to update Backup Offering [id: {}] due to: [{}].", id, e.getMessage(), e);
throw new ServerApiException(paramError, e.getMessage());
}
}
+ public List getDomainIds() {
+ // backupManager may be null in unit tests where the command is spied without injection.
+ // Avoid creating a method reference to a null receiver which causes NPE. When backupManager
+ // is null, pass null as the defaultDomainsProvider so resolveDomainIds will simply return
+ // an empty list or parse the explicit domainIds string.
+ LongFunction> defaultDomainsProvider = null;
+ if (backupManager != null) {
+ defaultDomainsProvider = backupManager::getBackupOfferingDomains;
+ }
+ return resolveDomainIds(domainIds, id, defaultDomainsProvider, "backup offering");
+ }
+
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
index 463af000f58b..79dad4269c9b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/IssueCertificateCmd.java
@@ -149,6 +149,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses;
+ return "Issuing certificate for domain(s)=" + domains + ", ip(s)=" + addresses;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
index af24e1f10c89..d333a74fdb3b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ca/ProvisionCertificateCmd.java
@@ -63,6 +63,12 @@ public class ProvisionCertificateCmd extends BaseAsyncCmd {
description = "Name of the CA service provider, otherwise the default configured provider plugin will be used")
private String provider;
+ @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN,
+ description = "When true, uses SSH to re-provision the agent's certificate, bypassing the NIO agent connection. " +
+ "Use this when agents are disconnected due to a CA change. Supported for KVM hosts and SystemVMs. Default is false",
+ since = "4.23.0")
+ private Boolean forced;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -79,6 +85,10 @@ public String getProvider() {
return provider;
}
+ public boolean isForced() {
+ return forced != null && forced;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -90,7 +100,7 @@ public void execute() {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find host by ID: " + getHostId());
}
- boolean result = caManager.provisionCertificate(host, getReconnect(), getProvider());
+ boolean result = caManager.provisionCertificate(host, getReconnect(), getProvider(), isForced());
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
setResponseObject(response);
@@ -108,7 +118,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Provisioning certificate for host id=" + hostId + " using provider=" + provider;
+ return "Provisioning certificate for host with ID: " + getResourceUuid(ApiConstants.HOST_ID) + " using provider: " + provider;
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
index 5d1c1f8a6fd5..d8fa2123d228 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
@@ -69,7 +69,7 @@ public class AddClusterCmd extends BaseCmd {
private String hypervisor;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "The CPU arch of the cluster. Valid options are: x86_64, aarch64",
+ description = "The CPU arch of the cluster. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
index 60f2c2b1deea..00e7da6e37c1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/ExecuteClusterDrsPlanCmd.java
@@ -142,6 +142,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return String.format("Executing DRS plan for cluster: %d", getId());
+ return "Executing DRS plan for cluster with ID: " + getResourceUuid(ApiConstants.ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
index 2e7cb217d27a..77d0557af05b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/cluster/UpdateClusterCmd.java
@@ -58,7 +58,7 @@ public class UpdateClusterCmd extends BaseCmd {
private String managedState;
@Parameter(name = ApiConstants.ARCH, type = CommandType.STRING,
- description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64",
+ description = "the CPU arch of the cluster. Valid options are: x86_64, aarch64, s390x",
since = "4.20")
private String arch;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
index f6f66415f533..055443934609 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java
@@ -19,23 +19,23 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.commons.lang3.StringUtils;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.Pair;
@@ -94,6 +94,13 @@ public class ListCfgsByCmd extends BaseListCmd {
description = "The ID of the Image Store to update the parameter value for corresponding image store")
private Long imageStoreId;
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Lists configuration by group name (primarily used for UI)", since = "4.18.0")
private String groupName;
@@ -139,6 +146,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
public String getGroupName() {
return groupName;
}
@@ -200,6 +211,9 @@ private void setScope(ConfigurationResponse cfgResponse) {
if (getImageStoreId() != null){
cfgResponse.setScope("imagestore");
}
+ if (getManagementServerId() != null){
+ cfgResponse.setScope("managementserver");
+ }
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
index 2d511cff34db..3c3c36b29d7e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/ResetCfgCmd.java
@@ -23,16 +23,16 @@
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ImageStoreResponse;
-import org.apache.cloudstack.framework.config.ConfigKey;
-
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@@ -84,6 +84,13 @@ public class ResetCfgCmd extends BaseCmd {
description = "The ID of the Image Store to reset the parameter value for corresponding image store")
private Long imageStoreId;
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -116,6 +123,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -149,6 +160,9 @@ public void execute() {
if (getImageStoreId() != null) {
response.setScope(ConfigKey.Scope.ImageStore.name());
}
+ if (getManagementServerId() != null) {
+ response.setScope(ConfigKey.Scope.ManagementServer.name());
+ }
response.setValue(cfg.second());
this.setResponseObject(response);
} else {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
index 2fad8d71c68b..9db9529dc8d8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java
@@ -16,9 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.admin.config;
-import com.cloud.utils.crypt.DBEncryptionUtil;
import org.apache.cloudstack.acl.RoleService;
-import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiArgValidator;
import org.apache.cloudstack.api.ApiConstants;
@@ -29,13 +27,17 @@
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConfigurationResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
+import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
+import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.commons.lang3.StringUtils;
import com.cloud.user.Account;
+import com.cloud.utils.crypt.DBEncryptionUtil;
@APICommand(name = "updateConfiguration", description = "Updates a configuration.", responseObject = ConfigurationResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -88,6 +90,13 @@ public class UpdateCfgCmd extends BaseCmd {
validations = ApiArgValidator.PositiveNumber)
private Long imageStoreId;
+ @Parameter(name = ApiConstants.MANAGEMENT_SERVER_ID,
+ type = CommandType.UUID,
+ entityType = ManagementServerResponse.class,
+ description = "the ID of the Management Server to update the parameter value for corresponding management server",
+ since = "4.23.0")
+ private Long managementServerId;
+
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@@ -112,7 +121,7 @@ public Long getClusterId() {
return clusterId;
}
- public Long getStoragepoolId() {
+ public Long getStoragePoolId() {
return storagePoolId;
}
@@ -128,6 +137,10 @@ public Long getImageStoreId() {
return imageStoreId;
}
+ public Long getManagementServerId() {
+ return managementServerId;
+ }
+
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@@ -150,7 +163,7 @@ public void execute() {
ConfigurationResponse response = _responseGenerator.createConfigurationResponse(cfg);
response.setResponseName(getCommandName());
response = setResponseScopes(response);
- response = setResponseValue(response, cfg);
+ setResponseValue(response, cfg);
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update config");
@@ -161,15 +174,13 @@ public void execute() {
* Sets the configuration value in the response. If the configuration is in the `Hidden` or `Secure` categories, the value is encrypted before being set in the response.
* @param response to be set with the configuration `cfg` value
* @param cfg to be used in setting the response value
- * @return the response with the configuration's value
*/
- public ConfigurationResponse setResponseValue(ConfigurationResponse response, Configuration cfg) {
+ public void setResponseValue(ConfigurationResponse response, Configuration cfg) {
+ String value = cfg.getValue();
if (cfg.isEncrypted()) {
- response.setValue(DBEncryptionUtil.encrypt(getValue()));
- } else {
- response.setValue(getValue());
+ value = DBEncryptionUtil.encrypt(value);
}
- return response;
+ response.setValue(value);
}
/**
@@ -184,7 +195,7 @@ public ConfigurationResponse setResponseScopes(ConfigurationResponse response) {
if (getClusterId() != null) {
response.setScope("cluster");
}
- if (getStoragepoolId() != null) {
+ if (getStoragePoolId() != null) {
response.setScope("storagepool");
}
if (getAccountId() != null) {
@@ -193,6 +204,9 @@ public ConfigurationResponse setResponseScopes(ConfigurationResponse response) {
if (getDomainId() != null) {
response.setScope("domain");
}
+ if (getManagementServerId() != null) {
+ response.setScope(ConfigKey.Scope.ManagementServer.name().toLowerCase());
+ }
return response;
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
index 6a59788715ee..c140de5aa01e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/GetDiagnosticsDataCmd.java
@@ -140,7 +140,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Getting diagnostics data files from System VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+ return "Getting diagnostics data files from System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
index 577d86146fdd..d1f22baf6604 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/diagnostics/RunDiagnosticsCmd.java
@@ -153,7 +153,7 @@ public ApiCommandResourceType getApiResourceType() {
@Override
public String getEventDescription() {
- return "Executing diagnostics on System VM: " + this._uuidMgr.getUuid(VirtualMachine.class, getId());
+ return "Executing diagnostics on System Instance with ID: " + getResourceUuid(ApiConstants.TARGET_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
index 780198dded59..ad440376a913 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
@@ -95,7 +95,7 @@ public void execute() {
}
try {
- logger.debug("Uploading certificate " + name + " to agents for Direct Download");
+ logger.debug("Uploading certificate {} to agents for Direct Download", name);
Pair> uploadStatus =
directDownloadManager.uploadCertificateToHosts(certificate, name, hypervisor, zoneId, hostId);
DirectDownloadCertificate certificate = uploadStatus.first();
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
index a20f69c90f58..d2775548a841 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/CreateDomainCmd.java
@@ -86,7 +86,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent DomainId :" + getParentDomainId() : ""));
+ CallContext.current().setEventDetails("Domain Name: " + getDomainName() + ((getParentDomainId() != null) ? ", Parent Domain ID:" + getResourceUuid(ApiConstants.PARENT_DOMAIN_ID) : ""));
Domain domain = _domainService.createDomain(getDomainName(), getParentDomainId(), getNetworkDomain(), getDomainUUID());
if (domain != null) {
DomainResponse response = _responseGenerator.createDomainResponse(domain);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
index 6adb457f4f83..cf02e6a56bf8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/DeleteDomainCmd.java
@@ -88,12 +88,12 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting domain: " + getId();
+ return "Deleting domain with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Id: " + getId());
+ CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _regionService.deleteDomain(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
index 5c5a92c45cac..aa1978042265 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java
@@ -23,7 +23,7 @@
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
-import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.UserCmd;
@@ -39,7 +39,7 @@
@APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, responseView = ResponseView.Restricted, entityType = {Domain.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class ListDomainsCmd extends BaseListCmd implements UserCmd {
+public class ListDomainsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
private static final String s_name = "listdomainsresponse";
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
index adce521627fb..124a84931548 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/domain/UpdateDomainCmd.java
@@ -82,7 +82,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Domain Id: " + getId());
+ CallContext.current().setEventDetails("Domain ID: " + getResourceUuid(ApiConstants.ID));
Domain domain = _regionService.updateDomain(this);
if (domain != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
index 2ac07a9fb3a0..83aca1a2eb64 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/gpu/DiscoverGpuDevicesCmd.java
@@ -46,7 +46,7 @@ public class DiscoverGpuDevicesCmd extends BaseListCmd {
@Override
public void execute() {
- CallContext.current().setEventDetails("Discovering GPU Devices on host id: " + getId());
+ CallContext.current().setEventDetails("Discovering GPU Devices on host with ID: " + getResourceUuid(ApiConstants.ID));
ListResponse response = gpuService.discoverGpuDevices(this);
response.setResponseName(getCommandName());
setResponseObject(response);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
index 1868d0412a18..c0e995c497d2 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
@@ -120,7 +120,7 @@ public void create() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Id: " + getEntityId());
+ CallContext.current().setEventDetails("Guest OS ID: " + getEntityUuid());
GuestOS guestOs = _mgr.getAddedGuestOs(getEntityId());
if (guestOs != null) {
GuestOSResponse response = _responseGenerator.createGuestOSResponse(guestOs);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
index d38682ce5bb4..f5c7d965c13f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
@@ -62,7 +62,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Id: " + id);
+ CallContext.current().setEventDetails("Guest OS ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _mgr.removeGuestOs(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -74,7 +74,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Removing Guest OS: " + getId();
+ return "Removing Guest OS with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
index a472ab672c55..bd4a53889f25 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
@@ -62,7 +62,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Guest OS Mapping Id: " + id);
+ CallContext.current().setEventDetails("Guest OS Mapping ID: " + getResourceUuid(ApiConstants.ID));
boolean result = _mgr.removeGuestOsMapping(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -74,7 +74,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Removing Guest OS Mapping: " + getId();
+ return "Removing Guest OS Mapping with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
index 59909e09854a..035ff6a19e24 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
@@ -123,7 +123,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Updating guest OS: " + getId();
+ return "Updating guest OS with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
index fc67ef0a7e76..161bb5323070 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
@@ -86,7 +86,7 @@ public long getEntityOwnerId() {
@Override
public String getEventDescription() {
- return "Updating Guest OS Mapping: " + getId();
+ return "Updating Guest OS with ID: " + getResourceUuid(ApiConstants.ID) + " mapping.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
index ed3b166e6ead..cb427e659495 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/ConfigureHAForHostCmd.java
@@ -103,7 +103,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
if (!result) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to configure HA provider for the host");
}
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA configured with provider: " + getHaProvider());
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA configured with provider: " + getHaProvider());
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -116,6 +116,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Configure HA for host: " + getHostId();
+ return "Configuring HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
index 51554b7607dc..63c657a9e454 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForClusterCmd.java
@@ -89,7 +89,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find cluster by ID: " + getClusterId());
}
final boolean result = haConfigManager.disableHA(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
setupResponse(result);
@@ -102,7 +102,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Disable HA for cluster: " + getClusterId();
+ return "Disabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
index ad9c64145322..b90f731ff565 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForHostCmd.java
@@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.disableHA(host.getId(), HAResource.ResourceType.Host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -104,6 +104,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Disable HA for host: " + getHostId();
+ return "Disabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
index 1f0758459b5d..07a6fbd2b399 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/DisableHAForZoneCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.disableHA(dataCenter);
- CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: false");
+ CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: false");
CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid());
setupResponse(result);
@@ -103,7 +103,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Disable HA for zone: " + getZoneId();
+ return "Disabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
index 3bb7a4c3070d..635fba988c60 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForClusterCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(cluster);
- CallContext.current().setEventDetails("Cluster Id:" + cluster.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Cluster ID:" + cluster.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(Cluster.class, cluster.getUuid());
setupResponse(result);
@@ -103,6 +103,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Enable HA for cluster: " + getClusterId();
+ return "Enabling HA for cluster with ID: " + getResourceUuid(ApiConstants.CLUSTER_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
index f54767225432..0bda19a7ad3c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForHostCmd.java
@@ -91,7 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(host.getId(), HAResource.ResourceType.Host);
- CallContext.current().setEventDetails("Host Id:" + host.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Host ID:" + host.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(Host.class, host.getUuid());
setupResponse(result, host.getUuid());
@@ -104,6 +104,6 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Enable HA for host: " + getHostId();
+ return "Enabling HA for host with ID: " + getResourceUuid(ApiConstants.HOST_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
index 99607315c543..f6d0f62bb120 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/ha/EnableHAForZoneCmd.java
@@ -90,7 +90,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
}
final boolean result = haConfigManager.enableHA(dataCenter);
- CallContext.current().setEventDetails("Zone Id:" + dataCenter.getId() + " HA enabled: true");
+ CallContext.current().setEventDetails("Zone ID:" + dataCenter.getUuid() + " HA enabled: true");
CallContext.current().putContextParameter(DataCenter.class, dataCenter.getUuid());
setupResponse(result);
@@ -103,7 +103,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Enable HA for zone: " + getZoneId();
+ return "Enabling HA for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
index f68da1edcd17..56930d47b2ec 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostAsDegradedCmd.java
@@ -78,7 +78,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "declaring host: " + getId() + " as Degraded";
+ return "Removing host with ID: " + getResourceUuid(ApiConstants.ID) + " from Degraded state.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
index 111172200b9a..5d44bafb4b5c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/CancelHostMaintenanceCmd.java
@@ -76,7 +76,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Canceling maintenance for host: " + getId();
+ return "Canceling maintenance for host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
index 209d8b65fbab..1dd65a583706 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/DeclareHostAsDegradedCmd.java
@@ -78,7 +78,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "declaring host: " + getId() + " as Degraded";
+ return "Declaring host with ID: " + getResourceUuid(ApiConstants.ID) + " as Degraded.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
index abca619f82a7..4d6ef7419616 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java
@@ -78,7 +78,7 @@ public void execute() {
for (Host host : result.first()) {
HostForMigrationResponse hostResponse = _responseGenerator.createHostForMigrationResponse(host);
Boolean suitableForMigration = false;
- if (hostsWithCapacity.contains(host)) {
+ if (hostsWithCapacity != null && hostsWithCapacity.contains(host)) {
suitableForMigration = true;
}
hostResponse.setSuitableForMigration(suitableForMigration);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
index e202dfad77ba..8f5e6c784d6e 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
@@ -252,7 +252,7 @@ protected ListResponse getHostResponses() {
for (Host host : result.first()) {
HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
Boolean suitableForMigration = false;
- if (hostsWithCapacity.contains(host)) {
+ if (hostsWithCapacity != null && hostsWithCapacity.contains(host)) {
suitableForMigration = true;
}
hostResponse.setSuitableForMigration(suitableForMigration);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
index b76f500359a3..843c7fd7fcbe 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/PrepareForHostMaintenanceCmd.java
@@ -76,7 +76,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "preparing host: " + getId() + " for maintenance";
+ return "Preparing host with ID: " + getResourceUuid(ApiConstants.ID) + " for maintenance.";
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
index 178a96cedbd6..b9892ed6033c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReconnectHostCmd.java
@@ -77,7 +77,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "reconnecting host: " + getId();
+ return "Reconnecting host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
index d7905421a8f3..bddb5b13e452 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/ReleaseHostReservationCmd.java
@@ -72,7 +72,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "releasing reservation for host: " + getId();
+ return "Releasing reservation from host with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
index 82699b40cdda..69bca7c79e21 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/host/UpdateHostCmd.java
@@ -49,9 +49,14 @@ public class UpdateHostCmd extends BaseCmd {
@Parameter(name = ApiConstants.OS_CATEGORY_ID,
type = CommandType.UUID,
entityType = GuestOSCategoryResponse.class,
- description = "The ID of OS category to update the host with")
+ description = "the ID of OS category used to prioritize VMs with matching OS category during the allocation process. " +
+ "It cannot be used alongside the 'guestosrule' parameter.")
private Long osCategoryId;
+ @Parameter(name = ApiConstants.GUEST_OS_RULE, type = CommandType.STRING, description = "the guest OS rule written in JavaScript to match with the OS of the VM." +
+ "It cannot be used alongside the 'oscategoryid' parameter.")
+ private String guestOsRule;
+
@Parameter(name = ApiConstants.ALLOCATION_STATE,
type = CommandType.STRING,
description = "Change resource state of host, valid values are [Enable, Disable]. Operation may failed if host in states not allowing Enable/Disable")
@@ -96,6 +101,10 @@ public Long getOsCategoryId() {
return osCategoryId;
}
+ public String getGuestOsRule() {
+ return guestOsRule;
+ }
+
public String getAllocationState() {
return allocationState;
}
@@ -147,7 +156,7 @@ public void execute() {
this.setResponseObject(hostResponse);
} catch (Exception e) {
Host host = _entityMgr.findById(Host.class, getId());
- logger.debug("Failed to update host: {} with id {}", host, getId(), e);
+ logger.error("Failed to update {}", host, e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, String.format("Failed to update host: %s with id %d, %s", host, getId(), e.getMessage()));
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
index 9bb28523ecad..51aa86546603 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/ConfigureInternalLoadBalancerElementCmd.java
@@ -84,12 +84,12 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "configuring internal load balancer element: " + id;
+ return "Configuring internal load balancer element with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- CallContext.current().setEventDetails("Internal load balancer element: " + id);
+ CallContext.current().setEventDetails("Internal load balancer element: " + getResourceUuid(ApiConstants.ID));
InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementById(id);
VirtualRouterProvider result = service.configureInternalLoadBalancerElement(getId(), getEnabled());
if (result != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
index 474bbc831e5c..aa9e5f1ba7f4 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/CreateInternalLoadBalancerElementCmd.java
@@ -74,7 +74,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Virtual router element Id: " + getEntityId());
+ CallContext.current().setEventDetails("Virtual router element ID: " + getEntityUuid());
InternalLoadBalancerElementService service = _networkService.getInternalLoadBalancerElementByNetworkServiceProviderId(getNspId());
VirtualRouterProvider result = service.getInternalLoadBalancerElement(getEntityId());
if (result != null) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
index b5aa3c8d9b07..d9d4e46726fc 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StartInternalLBVMCmd.java
@@ -88,7 +88,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "starting Internal LB Instance: " + getId();
+ return "Starting internal LB Instance with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -103,7 +103,7 @@ public Long getApiResourceId() {
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
- CallContext.current().setEventDetails("Internal LB Instance ID: " + getId());
+ CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID));
VirtualRouter result = null;
VirtualRouter router = _routerService.findRouter(getId());
if (router == null || router.getRole() != Role.INTERNAL_LB_VM) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
index 82eddb27c7dd..253c59e671e5 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/internallb/StopInternalLBVMCmd.java
@@ -86,7 +86,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Stopping Internal LB Instance: " + getId();
+ return "Stopping Internal LB Instance: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -105,7 +105,7 @@ public boolean isForced() {
@Override
public void execute() throws ConcurrentOperationException, ResourceUnavailableException {
- CallContext.current().setEventDetails("Internal LB Instance Id: " + getId());
+ CallContext.current().setEventDetails("Internal LB Instance ID: " + getResourceUuid(ApiConstants.ID));
VirtualRouter result = null;
VirtualRouter vm = _routerService.findRouter(getId());
if (vm == null || vm.getRole() != Role.INTERNAL_LB_VM) {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
index c4b9db3b7c38..b831a99cb0af 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/iso/ListIsoPermissionsCmdByAdmin.java
@@ -1,4 +1,4 @@
-// Licensedname = "listIsoPermissions", to the Apache Software Foundation (ASF) under one
+// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/kms/MigrateVolumesToKMSCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/kms/MigrateVolumesToKMSCmd.java
new file mode 100644
index 000000000000..358f7f749f6e
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/kms/MigrateVolumesToKMSCmd.java
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.kms;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandResourceType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.AsyncJobResponse;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.KMSKeyResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.kms.KMSException;
+import org.apache.cloudstack.kms.KMSKey;
+import org.apache.cloudstack.kms.KMSManager;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = "migrateVolumesToKMS",
+ description = "Migrates encrypted volumes to KMS",
+ responseObject = AsyncJobResponse.class,
+ since = "4.23.0",
+ authorized = {RoleType.Admin},
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false)
+public class MigrateVolumesToKMSCmd extends BaseAsyncCmd {
+
+ @Inject
+ private KMSManager kmsManager;
+
+ @Parameter(name = ApiConstants.ACCOUNT,
+ type = CommandType.STRING,
+ description = "Migrate volumes for specific account")
+ private String accountName;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "Domain ID")
+ private Long domainId;
+
+ @Parameter(name = ApiConstants.VOLUME_IDS,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = VolumeResponse.class,
+ required = true,
+ description = "List of volume IDs to migrate")
+ private List volumeIds;
+
+ @Parameter(name = ApiConstants.KMS_KEY_ID,
+ required = true,
+ type = CommandType.UUID,
+ entityType = KMSKeyResponse.class,
+ description = "KMS Key ID to use for migrating volumes")
+ private Long kmsKeyId;
+
+ public String getAccountName() {
+ return accountName;
+ }
+
+ public Long getDomainId() {
+ return domainId;
+ }
+
+ public List getVolumeIds() {
+ return volumeIds;
+ }
+
+ public Long getKmsKeyId() {
+ return kmsKeyId;
+ }
+
+ @Override
+ public void execute() {
+ try {
+ kmsManager.migrateVolumesToKMS(this);
+ } catch (KMSException e) {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
+ "Failed to migrate volumes to KMS: " + e.getMessage());
+ }
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ KMSKey key = _entityMgr.findById(KMSKey.class, kmsKeyId);
+ if (key != null) {
+ return key.getAccountId();
+ }
+ return CallContext.current().getCallingAccount().getId();
+ }
+
+ @Override
+ public String getEventType() {
+ return com.cloud.event.EventTypes.EVENT_VOLUME_MIGRATE_TO_KMS;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Migrating volumes to KMS key: " + _uuidMgr.getUuid(KMSKey.class, kmsKeyId);
+ }
+
+ @Override
+ public ApiCommandResourceType getApiResourceType() {
+ return ApiCommandResourceType.KmsKey;
+ }
+
+ @Override
+ public Long getApiResourceId() {
+ return kmsKeyId;
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
index a0013f9d6e2b..3e42a0103d8b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/AddNetworkServiceProviderCmd.java
@@ -101,7 +101,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Network ServiceProvider Id: " + getEntityId());
+ CallContext.current().setEventDetails("Network ServiceProvider ID: " + getEntityUuid());
PhysicalNetworkServiceProvider result = _networkService.getCreatedPhysicalNetworkServiceProvider(getEntityId());
if (result != null) {
ProviderResponse response = _responseGenerator.createNetworkServiceProviderResponse(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java
new file mode 100644
index 000000000000..19760ffaaa10
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.network;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.NetworkOfferingResponse;
+
+import com.cloud.offering.NetworkOffering;
+
+@APICommand(name = "cloneNetworkOffering",
+ description = "Clones a network offering. All parameters are copied from the source offering unless explicitly overridden. " +
+ "Use 'addServices' and 'dropServices' to modify the service list without respecifying everything.",
+ responseObject = NetworkOfferingResponse.class,
+ requestHasSensitiveInfo = false,
+ responseHasSensitiveInfo = false,
+ since = "4.23.0")
+public class CloneNetworkOfferingCmd extends NetworkOfferingBaseCmd {
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.SOURCE_OFFERING_ID,
+ type = BaseCmd.CommandType.UUID,
+ entityType = NetworkOfferingResponse.class,
+ required = true,
+ description = "The ID of the source network offering to clone from")
+ private Long sourceOfferingId;
+
+ @Parameter(name = "addservices",
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services to add to the cloned offering (in addition to source offering services). " +
+ "If specified along with 'supportedservices', this parameter is ignored.")
+ private List addServices;
+
+ @Parameter(name = "dropservices",
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services to remove from the cloned offering (that exist in source offering). " +
+ "If specified along with 'supportedservices', this parameter is ignored.")
+ private List dropServices;
+
+ @Parameter(name = ApiConstants.TRAFFIC_TYPE,
+ type = CommandType.STRING,
+ description = "The traffic type for the network offering. Supported type in current release is GUEST only")
+ private String traffictype;
+
+ @Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, description = "Guest type of the network offering: Shared or Isolated")
+ private String guestIptype;
+
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public Long getSourceOfferingId() {
+ return sourceOfferingId;
+ }
+
+ public List getAddServices() {
+ return addServices;
+ }
+
+ public List getDropServices() {
+ return dropServices;
+ }
+
+ public String getGuestIpType() {
+ return guestIptype;
+ }
+
+ public String getTraffictype() {
+ return traffictype;
+ }
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public void execute() {
+ NetworkOffering result = _configService.cloneNetworkOffering(this);
+ if (result != null) {
+ NetworkOfferingResponse response = _responseGenerator.createNetworkOfferingResponse(result);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone network offering");
+ }
+ }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
index f6b035c57837..614dcf9d0751 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateGuestNetworkIpv6PrefixCmd.java
@@ -83,7 +83,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv6 prefix " + getPrefix() + " for zone=" + getZoneId();
+ return "Creating guest IPv6 prefix " + getPrefix() + " for zone with ID: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
index a482cb1d4f27..4d645376a909 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForGuestNetworkCmd.java
@@ -85,7 +85,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet=" + getParentId();
+ return "Creating guest IPv4 subnet " + getSubnet() + " in zone subnet: " + getResourceUuid(ApiConstants.PARENT_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
index 5f48cf9c6327..48a6002fb5c0 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateIpv4SubnetForZoneCmd.java
@@ -102,7 +102,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating guest IPv4 subnet " + getSubnet() + " for zone=" + getZoneId();
+ return "Creating guest IPv4 subnet " + getSubnet() + " for zone: " + getResourceUuid(ApiConstants.ZONE_ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
index a7826e022a68..2780c4eaf050 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateManagementNetworkIpRangeCmd.java
@@ -132,7 +132,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Creating management ip range from " + getStartIp() + " to " + getEndIp() + " and gateway=" + getGateWay() + ", netmask=" + getNetmask() + " of pod=" + getPodId();
+ return "Creating management IP range from " + getStartIp() + " to " + getEndIp() + ", with gateway: " + getGateWay() + ", netmask:" + getNetmask() + " on pod:" + getPodId();
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index a0559f57dab0..5c39060f9fa3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -16,505 +16,47 @@
// under the License.
package org.apache.cloudstack.api.command.admin.network;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.cloud.network.Network;
-import com.cloud.network.VirtualRouterProvider;
-import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkOfferingResponse;
-import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.network.Network.Capability;
-import com.cloud.network.Network.Service;
import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.NetworkOffering.Availability;
-import com.cloud.user.Account;
-
-import static com.cloud.network.Network.Service.Dhcp;
-import static com.cloud.network.Network.Service.Dns;
-import static com.cloud.network.Network.Service.Lb;
-import static com.cloud.network.Network.Service.StaticNat;
-import static com.cloud.network.Network.Service.SourceNat;
-import static com.cloud.network.Network.Service.PortForwarding;
-import static com.cloud.network.Network.Service.NetworkACL;
-import static com.cloud.network.Network.Service.UserData;
-import static com.cloud.network.Network.Service.Firewall;
-
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
-import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNsxWithoutLb;
@APICommand(name = "createNetworkOffering", description = "Creates a network offering.", responseObject = NetworkOfferingResponse.class, since = "3.0.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
-public class CreateNetworkOfferingCmd extends BaseCmd {
+public class CreateNetworkOfferingCmd extends NetworkOfferingBaseCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
- @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the network offering")
- private String networkOfferingName;
-
- @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the network offering, defaults to the value of 'name'.")
- private String displayText;
-
@Parameter(name = ApiConstants.TRAFFIC_TYPE,
type = CommandType.STRING,
required = true,
description = "The traffic type for the network offering. Supported type in current release is GUEST only")
private String traffictype;
- @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "The tags for the network offering.", length = 4096)
- private String tags;
-
- @Parameter(name = ApiConstants.SPECIFY_VLAN, type = CommandType.BOOLEAN, description = "True if network offering supports VLANs")
- private Boolean specifyVlan;
-
- @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "The availability of network offering. The default value is Optional. "
- + " Another value is Required, which will make it as the default network offering for new networks ")
- private String availability;
-
- @Parameter(name = ApiConstants.NETWORKRATE, type = CommandType.INTEGER, description = "Data transfer rate in megabits per second allowed")
- private Integer networkRate;
-
- @Parameter(name = ApiConstants.CONSERVE_MODE, type = CommandType.BOOLEAN, description = "True if the network offering is IP conserve mode enabled")
- private Boolean conserveMode;
-
- @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
- type = CommandType.UUID,
- entityType = ServiceOfferingResponse.class,
- description = "The service offering ID used by virtual router provider")
- private Long serviceOfferingId;
-
@Parameter(name = ApiConstants.GUEST_IP_TYPE, type = CommandType.STRING, required = true, description = "Guest type of the network offering: Shared or Isolated")
private String guestIptype;
- @Parameter(name = ApiConstants.INTERNET_PROTOCOL,
- type = CommandType.STRING,
- description = "The internet protocol of network offering. Options are IPv4 and dualstack. Default is IPv4. dualstack will create a network offering that supports both IPv4 and IPv6",
- since = "4.17.0")
- private String internetProtocol;
-
- @Parameter(name = ApiConstants.SUPPORTED_SERVICES,
- type = CommandType.LIST,
- collectionType = CommandType.STRING,
- description = "Services supported by the network offering")
- private List supportedServices;
-
- @Parameter(name = ApiConstants.SERVICE_PROVIDER_LIST,
- type = CommandType.MAP,
- description = "Provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network")
- private Map serviceProviderList;
-
- @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "Desired service capabilities as part of network offering")
- private Map serviceCapabilitystList;
-
- @Parameter(name = ApiConstants.SPECIFY_IP_RANGES,
- type = CommandType.BOOLEAN,
- description = "True if network offering supports specifying ip ranges; defaulted to false if not specified")
- private Boolean specifyIpRanges;
-
- @Parameter(name = ApiConstants.IS_PERSISTENT,
- type = CommandType.BOOLEAN,
- description = "True if network offering supports persistent networks; defaulted to false if not specified")
- private Boolean isPersistent;
-
- @Parameter(name = ApiConstants.FOR_VPC,
- type = CommandType.BOOLEAN,
- description = "True if network offering is meant to be used for VPC, false otherwise.")
- private Boolean forVpc;
-
- @Deprecated
- @Parameter(name = ApiConstants.FOR_NSX,
- type = CommandType.BOOLEAN,
- description = "true if network offering is meant to be used for NSX, false otherwise.",
- since = "4.20.0")
- private Boolean forNsx;
-
- @Parameter(name = ApiConstants.PROVIDER,
- type = CommandType.STRING,
- description = "Name of the provider providing the service",
- since = "4.21.0")
- private String provider;
-
- @Parameter(name = ApiConstants.NSX_SUPPORT_LB,
- type = CommandType.BOOLEAN,
- description = "True if network offering for NSX network offering supports Load balancer service.",
- since = "4.20.0")
- private Boolean nsxSupportsLbService;
-
- @Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
- type = CommandType.BOOLEAN,
- description = "True if network offering for NSX network offering supports Internal Load balancer service.",
- since = "4.20.0")
- private Boolean nsxSupportsInternalLbService;
-
- @Parameter(name = ApiConstants.NETWORK_MODE,
- type = CommandType.STRING,
- description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
- since = "4.20.0")
- private String networkMode;
-
- @Parameter(name = ApiConstants.FOR_TUNGSTEN,
- type = CommandType.BOOLEAN,
- description = "True if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
- private Boolean forTungsten;
-
- @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
- + " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
- + " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
- protected Map details;
-
- @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
- type = CommandType.BOOLEAN,
- description = "True if guest network default egress policy is allow; false if default egress policy is deny")
- private Boolean egressDefaultPolicy;
-
- @Parameter(name = ApiConstants.KEEPALIVE_ENABLED,
- type = CommandType.BOOLEAN,
- required = false,
- description = "If true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
- private Boolean keepAliveEnabled;
-
- @Parameter(name = ApiConstants.MAX_CONNECTIONS,
- type = CommandType.INTEGER,
- description = "Maximum number of concurrent connections supported by the Network offering")
- private Integer maxConnections;
-
- @Parameter(name = ApiConstants.DOMAIN_ID,
- type = CommandType.LIST,
- collectionType = CommandType.UUID,
- entityType = DomainResponse.class,
- description = "The ID of the containing domain(s), null for public offerings")
- private List domainIds;
-
- @Parameter(name = ApiConstants.ZONE_ID,
- type = CommandType.LIST,
- collectionType = CommandType.UUID,
- entityType = ZoneResponse.class,
- description = "The ID of the containing zone(s), null for public offerings",
- since = "4.13")
- private List zoneIds;
-
- @Parameter(name = ApiConstants.ENABLE,
- type = CommandType.BOOLEAN,
- description = "Set to true if the offering is to be enabled during creation. Default is false",
- since = "4.16")
- private Boolean enable;
-
- @Parameter(name = ApiConstants.SPECIFY_AS_NUMBER, type = CommandType.BOOLEAN, since = "4.20.0",
- description = "true if network offering supports choosing AS number")
- private Boolean specifyAsNumber;
-
- @Parameter(name = ApiConstants.ROUTING_MODE,
- type = CommandType.STRING,
- since = "4.20.0",
- description = "the routing mode for the network offering. Supported types are: Static or Dynamic.")
- private String routingMode;
-
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
- public String getNetworkOfferingName() {
- return networkOfferingName;
- }
-
- public String getDisplayText() {
- return StringUtils.isEmpty(displayText) ? networkOfferingName : displayText;
- }
-
- public String getTags() {
- return tags;
- }
-
public String getTraffictype() {
return traffictype;
}
- public Boolean getSpecifyVlan() {
- return specifyVlan == null ? false : specifyVlan;
- }
-
- public String getAvailability() {
- return availability == null ? Availability.Optional.toString() : availability;
- }
-
- public Integer getNetworkRate() {
- return networkRate;
- }
-
- public Long getServiceOfferingId() {
- return serviceOfferingId;
- }
-
- public boolean isExternalNetworkProvider() {
- return Arrays.asList("NSX", "Netris").stream()
- .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
- }
-
- public boolean isForNsx() {
- return provider != null && provider.equalsIgnoreCase("NSX");
- }
-
- public boolean isForNetris() {
- return provider != null && provider.equalsIgnoreCase("Netris");
- }
-
- public String getProvider() {
- return provider;
- }
-
- public List getSupportedServices() {
- if (!isExternalNetworkProvider()) {
- return supportedServices == null ? new ArrayList() : supportedServices;
- } else {
- List services = new ArrayList<>(List.of(
- Dhcp.getName(),
- Dns.getName(),
- UserData.getName()
- ));
- if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
- services.addAll(Arrays.asList(
- StaticNat.getName(),
- SourceNat.getName(),
- PortForwarding.getName()));
- }
- if (getNsxSupportsLbService() || (provider != null && isNetrisNatted(getProvider(), getNetworkMode()))) {
- services.add(Lb.getName());
- }
- if (Boolean.TRUE.equals(forVpc)) {
- services.add(NetworkACL.getName());
- } else {
- services.add(Firewall.getName());
- }
- return services;
- }
- }
-
public String getGuestIpType() {
return guestIptype;
}
- public String getInternetProtocol() {
- return internetProtocol;
- }
-
- public Boolean getSpecifyIpRanges() {
- return specifyIpRanges == null ? false : specifyIpRanges;
- }
-
- public Boolean getConserveMode() {
- if (conserveMode == null) {
- return true;
- }
- return conserveMode;
- }
-
- public Boolean getIsPersistent() {
- return isPersistent == null ? false : isPersistent;
- }
-
- public Boolean getForVpc() {
- return forVpc;
- }
-
- public String getNetworkMode() {
- return networkMode;
- }
-
- public boolean getNsxSupportsLbService() {
- return BooleanUtils.isTrue(nsxSupportsLbService);
- }
-
- public boolean getNsxSupportsInternalLbService() {
- return BooleanUtils.isTrue(nsxSupportsInternalLbService);
- }
-
- public Boolean getForTungsten() {
- return forTungsten;
- }
-
- public Boolean getEgressDefaultPolicy() {
- if (egressDefaultPolicy == null) {
- return true;
- }
- return egressDefaultPolicy;
- }
-
- public Boolean getKeepAliveEnabled() {
- return keepAliveEnabled;
- }
-
- public Integer getMaxconnections() {
- return maxConnections;
- }
-
- public Map> getServiceProviders() {
- Map> serviceProviderMap = new HashMap<>();
- if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
- Collection servicesCollection = serviceProviderList.values();
- Iterator iter = servicesCollection.iterator();
- while (iter.hasNext()) {
- HashMap services = (HashMap) iter.next();
- String service = services.get("service");
- String provider = services.get("provider");
- List providerList = null;
- if (serviceProviderMap.containsKey(service)) {
- providerList = serviceProviderMap.get(service);
- } else {
- providerList = new ArrayList();
- }
- providerList.add(provider);
- serviceProviderMap.put(service, providerList);
- }
- } else if (isExternalNetworkProvider()) {
- getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
- }
- return serviceProviderMap;
- }
-
- private void getServiceProviderMapForExternalProvider(Map> serviceProviderMap, String provider) {
- String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
- VirtualRouterProvider.Type.VirtualRouter.name();
- List unsupportedServices = new ArrayList<>(List.of("Vpn", "Gateway", "SecurityGroup", "Connectivity", "BaremetalPxeService"));
- List routerSupported = List.of("Dhcp", "Dns", "UserData");
- List allServices = Service.listAllServices().stream().map(Service::getName).collect(Collectors.toList());
- if (routerProvider.equals(VirtualRouterProvider.Type.VPCVirtualRouter.name())) {
- unsupportedServices.add("Firewall");
- } else {
- unsupportedServices.add("NetworkACL");
- }
- for (String service : allServices) {
- if (unsupportedServices.contains(service))
- continue;
- if (routerSupported.contains(service))
- serviceProviderMap.put(service, List.of(routerProvider));
- else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode()) || NetworkACL.getName().equalsIgnoreCase(service)) {
- serviceProviderMap.put(service, List.of(provider));
- }
- if (isNsxWithoutLb(getProvider(), getNsxSupportsLbService()) || isNetrisRouted(getProvider(), getNetworkMode())) {
- serviceProviderMap.remove(Lb.getName());
- }
- }
- }
-
- public Map getServiceCapabilities(Service service) {
- Map capabilityMap = null;
-
- if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
- capabilityMap = new HashMap();
- Collection serviceCapabilityCollection = serviceCapabilitystList.values();
- Iterator iter = serviceCapabilityCollection.iterator();
- while (iter.hasNext()) {
- HashMap svcCapabilityMap = (HashMap) iter.next();
- Capability capability = null;
- String svc = svcCapabilityMap.get("service");
- String capabilityName = svcCapabilityMap.get("capabilitytype");
- String capabilityValue = svcCapabilityMap.get("capabilityvalue");
-
- if (capabilityName != null) {
- capability = Capability.getCapability(capabilityName);
- }
-
- if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
- throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
- }
-
- if (svc.equalsIgnoreCase(service.getName())) {
- capabilityMap.put(capability, capabilityValue);
- } else {
- //throw new InvalidParameterValueException("Service is not equal ")
- }
- }
- }
-
- return capabilityMap;
- }
-
- public Map getDetails() {
- if (details == null || details.isEmpty()) {
- return null;
- }
-
- Collection paramsCollection = details.values();
- Object objlist[] = paramsCollection.toArray();
- Map params = (Map) (objlist[0]);
- for (int i = 1; i < objlist.length; i++) {
- params.putAll((Map) (objlist[i]));
- }
-
- return params;
- }
-
- public String getServicePackageId() {
- Map data = getDetails();
- if (data == null)
- return null;
- return data.get(NetworkOffering.Detail.servicepackageuuid + "");
- }
-
- public List getDomainIds() {
- if (CollectionUtils.isNotEmpty(domainIds)) {
- Set set = new LinkedHashSet<>(domainIds);
- domainIds.clear();
- domainIds.addAll(set);
- }
- return domainIds;
- }
-
- public List getZoneIds() {
- if (CollectionUtils.isNotEmpty(zoneIds)) {
- Set set = new LinkedHashSet<>(zoneIds);
- zoneIds.clear();
- zoneIds.addAll(set);
- }
- return zoneIds;
- }
-
- public Boolean getEnable() {
- if (enable != null) {
- return enable;
- }
- return false;
- }
-
- public boolean getSpecifyAsNumber() {
- return BooleanUtils.toBoolean(specifyAsNumber);
- }
-
- public String getRoutingMode() {
- return routingMode;
- }
-
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
- @Override
- public long getEntityOwnerId() {
- return Account.ACCOUNT_ID_SYSTEM;
- }
@Override
public void execute() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
index f4ce9483bfbd..097b8a5b5458 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreatePhysicalNetworkCmd.java
@@ -75,7 +75,7 @@ public class CreatePhysicalNetworkCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.ISOLATION_METHODS,
type = CommandType.LIST,
collectionType = CommandType.STRING,
- description = "The isolation method for the physical Network[VLAN/L3/GRE]")
+ description = "The isolation method for the physical Network[VLAN/VXLAN/GRE/STT/BCF_SEGMENT/SSP/ODL/L3VPN/VCS/NSX/NETRIS]")
private List isolationMethods;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the physical Network")
@@ -148,7 +148,7 @@ public String getEventDescription() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Physical Network ID: " + getEntityId());
+ CallContext.current().setEventDetails("Physical Network ID: " + getEntityUuid());
PhysicalNetwork result = _networkService.getCreatedPhysicalNetwork(getEntityId());
if (result != null) {
PhysicalNetworkResponse response = _responseGenerator.createPhysicalNetworkResponse(result);
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
index 2df032c559c5..cc76b284e24a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DedicateIpv4SubnetForZoneCmd.java
@@ -82,7 +82,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Dedicating zone IPv4 subnet " + getId();
+ return "Dedicating zone's IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
index e2ada4191a82..405bbb594edb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteGuestNetworkIpv6PrefixCmd.java
@@ -63,7 +63,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting guest IPv6 prefix " + getId();
+ return "Deleting guest IPv6 prefix with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
index 28a646f9d036..f6b22f79dfc7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForGuestNetworkCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting guest IPv4 subnet " + getId();
+ return "Deleting guest IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
index 222bc1bad98d..0ff2a9ad70b8 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteIpv4SubnetForZoneCmd.java
@@ -59,7 +59,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting zone IPv4 subnet " + getId();
+ return "Deleting zone IPv4 subnet with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
index 41cf5e518b34..1e69aaa6c440 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteManagementNetworkIpRangeCmd.java
@@ -100,7 +100,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting management ip range from " + getStartIp() + " to " + getEndIp() + " of Pod: " + getPodId();
+ return "Deleting management IP range from " + getStartIp() + " to " + getEndIp() + " from Pod: " + getResourceUuid(ApiConstants.POD_ID);
}
@Override
@@ -116,7 +116,7 @@ public void execute() {
logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (Exception e) {
- logger.warn("Failed to delete management ip range from " + getStartIp() + " to " + getEndIp() + " of Pod: " + getPodId(), e);
+ logger.warn("Failed to delete management ip range from {} to {} of Pod: {}", getStartIp(), getEndIp(), getPodId(), e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
index 23d14966c49b..2573e92b9860 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteNetworkServiceProviderCmd.java
@@ -91,7 +91,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting Physical network ServiceProvider: " + getId();
+ return "Deleting Physical network ServiceProvider with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
index 70c35716b657..9994e8e391d7 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeletePhysicalNetworkCmd.java
@@ -65,7 +65,7 @@ public long getEntityOwnerId() {
@Override
public void execute() {
- CallContext.current().setEventDetails("Physical Network Id: " + id);
+ CallContext.current().setEventDetails("Physical Network Id: " + getResourceUuid(ApiConstants.ID));
boolean result = _networkService.deletePhysicalNetwork(getId());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@@ -77,7 +77,7 @@ public void execute() {
@Override
public String getEventDescription() {
- return "Deleting Physical network: " + getId();
+ return "Deleting Physical network with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
index d12135cc60c4..dcab38561408 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/DeleteStorageNetworkIpRangeCmd.java
@@ -64,7 +64,7 @@ public String getEventType() {
@Override
public String getEventDescription() {
- return "Deleting storage ip range " + getId();
+ return "Deleting storage IP range with ID: " + getResourceUuid(ApiConstants.ID);
}
@Override
@@ -75,7 +75,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} catch (Exception e) {
- logger.warn("Failed to delete storage network ip range " + getId(), e);
+ logger.warn("Failed to delete storage network ip range {}", getId(), e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
index c269be933735..3e32bed3d500 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/ListStorageNetworkIpRangeCmd.java
@@ -97,7 +97,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (Exception e) {
- logger.warn("Failed to list storage Network IP range for rangeId=" + getRangeId() + " podId=" + getPodId() + " zoneId=" + getZoneId());
+ logger.warn("Failed to list storage Network IP range for rangeId={} podId={} zoneId={}", getRangeId(), getPodId(), getZoneId());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
index 8ac9c8da691d..ad78bd3b406c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateNetworkCmd.java
@@ -115,7 +115,7 @@ public void execute() {
@Override
public String getEventDescription() {
- StringBuilder eventMsg = new StringBuilder("Migrating network: " + getId());
+ String description = "Migrating Network with ID: " + getResourceUuid(ApiConstants.NETWORK_ID);
if (getNetworkOfferingId() != null) {
Network network = _networkService.getNetwork(getId());
if (network == null) {
@@ -128,11 +128,11 @@ public String getEventDescription() {
throw new InvalidParameterValueException("Network offering id supplied is invalid");
}
- eventMsg.append(". Original network offering id: " + oldOff.getUuid() + ", new network offering id: " + newOff.getUuid());
+ description += ". Original Network Offering id: " + oldOff.getUuid() + ", new Network Offering id: " + newOff.getUuid();
}
}
- return eventMsg.toString();
+ return description;
}
@Override
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
index edef1f846ed7..2973fea33c6a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/MigrateVPCCmd.java
@@ -120,7 +120,7 @@ public void execute() {
}
@Override
- public String getEventDescription() { return "Migrating VPC : " + getId() + " to new VPC offering (" + vpcOfferingId + ")"; }
+ public String getEventDescription() { return "Migrating VPC with ID: " + getResourceUuid(ApiConstants.VPC_ID) + " to new VPC offering with ID: " + getResourceUuid(ApiConstants.VPC_OFF_ID);}
@Override
public String getEventType() {
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
new file mode 100644
index 000000000000..9b42be137314
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/NetworkOfferingBaseCmd.java
@@ -0,0 +1,494 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.network;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.VirtualRouterProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.cloud.network.Network.Service.Dhcp;
+import static com.cloud.network.Network.Service.Dns;
+import static com.cloud.network.Network.Service.Firewall;
+import static com.cloud.network.Network.Service.Lb;
+import static com.cloud.network.Network.Service.NetworkACL;
+import static com.cloud.network.Network.Service.PortForwarding;
+import static com.cloud.network.Network.Service.SourceNat;
+import static com.cloud.network.Network.Service.StaticNat;
+import static com.cloud.network.Network.Service.UserData;
+
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNsxWithoutLb;
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisNatted;
+import static org.apache.cloudstack.api.command.utils.OfferingUtils.isNetrisRouted;
+
+public abstract class NetworkOfferingBaseCmd extends BaseCmd {
+
+ public abstract String getGuestIpType();
+ public abstract String getTraffictype();
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "The name of the network offering")
+ private String networkOfferingName;
+
+ @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "The display text of the network offering, defaults to the value of 'name'.")
+ private String displayText;
+
+ @Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "The tags for the network offering.", length = 4096)
+ private String tags;
+
+ @Parameter(name = ApiConstants.SPECIFY_VLAN, type = CommandType.BOOLEAN, description = "True if network offering supports VLANs")
+ private Boolean specifyVlan;
+
+ @Parameter(name = ApiConstants.AVAILABILITY, type = CommandType.STRING, description = "The availability of network offering. The default value is Optional. "
+ + " Another value is Required, which will make it as the default network offering for new networks ")
+ private String availability;
+
+ @Parameter(name = ApiConstants.NETWORKRATE, type = CommandType.INTEGER, description = "Data transfer rate in megabits per second allowed")
+ private Integer networkRate;
+
+ @Parameter(name = ApiConstants.CONSERVE_MODE, type = CommandType.BOOLEAN, description = "True if the network offering is IP conserve mode enabled")
+ private Boolean conserveMode;
+
+ @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
+ type = CommandType.UUID,
+ entityType = ServiceOfferingResponse.class,
+ description = "The service offering ID used by virtual router provider")
+ private Long serviceOfferingId;
+
+ @Parameter(name = ApiConstants.INTERNET_PROTOCOL,
+ type = CommandType.STRING,
+ description = "The internet protocol of network offering. Options are IPv4 and dualstack. Default is IPv4. dualstack will create a network offering that supports both IPv4 and IPv6",
+ since = "4.17.0")
+ private String internetProtocol;
+
+ @Parameter(name = ApiConstants.SUPPORTED_SERVICES,
+ type = CommandType.LIST,
+ collectionType = CommandType.STRING,
+ description = "Services supported by the network offering")
+ private List supportedServices;
+
+ @Parameter(name = ApiConstants.SERVICE_PROVIDER_LIST,
+ type = CommandType.MAP,
+ description = "Provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network")
+ private Map serviceProviderList;
+
+ @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "Desired service capabilities as part of network offering")
+ private Map serviceCapabilitiesList;
+
+ @Parameter(name = ApiConstants.SPECIFY_IP_RANGES,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering supports specifying ip ranges; defaulted to false if not specified")
+ private Boolean specifyIpRanges;
+
+ @Parameter(name = ApiConstants.IS_PERSISTENT,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering supports persistent networks; defaulted to false if not specified")
+ private Boolean isPersistent;
+
+ @Parameter(name = ApiConstants.FOR_VPC,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering is meant to be used for VPC, false otherwise.")
+ private Boolean forVpc;
+
+ @Deprecated
+ @Parameter(name = ApiConstants.FOR_NSX,
+ type = CommandType.BOOLEAN,
+ description = "true if network offering is meant to be used for NSX, false otherwise.",
+ since = "4.20.0")
+ private Boolean forNsx;
+
+ @Parameter(name = ApiConstants.PROVIDER,
+ type = CommandType.STRING,
+ description = "Name of the provider providing the service",
+ since = "4.21.0")
+ private String provider;
+
+ @Parameter(name = ApiConstants.NSX_SUPPORT_LB,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering for NSX network offering supports Load balancer service.",
+ since = "4.20.0")
+ private Boolean nsxSupportsLbService;
+
+ @Parameter(name = ApiConstants.NSX_SUPPORTS_INTERNAL_LB,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering for NSX network offering supports Internal Load balancer service.",
+ since = "4.20.0")
+ private Boolean nsxSupportsInternalLbService;
+
+ @Parameter(name = ApiConstants.NETWORK_MODE,
+ type = CommandType.STRING,
+ description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED",
+ since = "4.20.0")
+ private String networkMode;
+
+ @Parameter(name = ApiConstants.FOR_TUNGSTEN,
+ type = CommandType.BOOLEAN,
+ description = "True if network offering is meant to be used for Tungsten-Fabric, false otherwise.")
+ private Boolean forTungsten;
+
+ @Parameter(name = ApiConstants.DETAILS, type = CommandType.MAP, since = "4.2.0", description = "Network offering details in key/value pairs."
+ + " Supported keys are internallbprovider/publiclbprovider with service provider as a value, and"
+ + " promiscuousmode/macaddresschanges/forgedtransmits with true/false as value to accept/reject the security settings if available for a nic/portgroup")
+ protected Map details;
+
+ @Parameter(name = ApiConstants.EGRESS_DEFAULT_POLICY,
+ type = CommandType.BOOLEAN,
+ description = "True if guest network default egress policy is allow; false if default egress policy is deny")
+ private Boolean egressDefaultPolicy;
+
+ @Parameter(name = ApiConstants.KEEPALIVE_ENABLED,
+ type = CommandType.BOOLEAN,
+ required = false,
+ description = "If true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file.")
+ private Boolean keepAliveEnabled;
+
+ @Parameter(name = ApiConstants.MAX_CONNECTIONS,
+ type = CommandType.INTEGER,
+ description = "Maximum number of concurrent connections supported by the Network offering")
+ private Integer maxConnections;
+
+ @Parameter(name = ApiConstants.DOMAIN_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = DomainResponse.class,
+ description = "The ID of the containing domain(s), null for public offerings")
+ private List domainIds;
+
+ @Parameter(name = ApiConstants.ZONE_ID,
+ type = CommandType.LIST,
+ collectionType = CommandType.UUID,
+ entityType = ZoneResponse.class,
+ description = "The ID of the containing zone(s), null for public offerings",
+ since = "4.13")
+ private List zoneIds;
+
+ @Parameter(name = ApiConstants.ENABLE,
+ type = CommandType.BOOLEAN,
+ description = "Set to true if the offering is to be enabled during creation. Default is false",
+ since = "4.16")
+ private Boolean enable;
+
+ @Parameter(name = ApiConstants.SPECIFY_AS_NUMBER, type = CommandType.BOOLEAN, since = "4.20.0",
+ description = "true if network offering supports choosing AS number")
+ private Boolean specifyAsNumber;
+
+ @Parameter(name = ApiConstants.ROUTING_MODE,
+ type = CommandType.STRING,
+ since = "4.20.0",
+ description = "the routing mode for the network offering. Supported types are: Static or Dynamic.")
+ private String routingMode;
+
+ private Map sourceDetailsMap;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+ public String getNetworkOfferingName() {
+ return networkOfferingName;
+ }
+
+ public String getDisplayText() {
+ return StringUtils.isEmpty(displayText) ? networkOfferingName : displayText;
+ }
+
+ public String getTags() {
+ return tags;
+ }
+
+ public Boolean getSpecifyVlan() {
+ return specifyVlan == null ? false : specifyVlan;
+ }
+
+ public String getAvailability() {
+ return availability == null ? NetworkOffering.Availability.Optional.toString() : availability;
+ }
+
+ public Integer getNetworkRate() {
+ return networkRate;
+ }
+
+ public Long getServiceOfferingId() {
+ return serviceOfferingId;
+ }
+
+ public boolean isExternalNetworkProvider() {
+ return Arrays.asList("NSX", "Netris").stream()
+ .anyMatch(s -> provider != null && s.equalsIgnoreCase(provider));
+ }
+
+ public boolean isForNsx() {
+ return provider != null && provider.equalsIgnoreCase("NSX");
+ }
+
+ public boolean isForNetris() {
+ return provider != null && provider.equalsIgnoreCase("Netris");
+ }
+
+ public String getProvider() {
+ return provider;
+ }
+
+ public List getSupportedServices() {
+ if (!isExternalNetworkProvider()) {
+ return supportedServices == null ? new ArrayList() : supportedServices;
+ } else {
+ List services = new ArrayList<>(List.of(
+ Dhcp.getName(),
+ Dns.getName(),
+ UserData.getName()
+ ));
+ if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMode())) {
+ services.addAll(Arrays.asList(
+ StaticNat.getName(),
+ SourceNat.getName(),
+ PortForwarding.getName()));
+ }
+ if (getNsxSupportsLbService() || (provider != null && isNetrisNatted(getProvider(), getNetworkMode()))) {
+ services.add(Lb.getName());
+ }
+ if (Boolean.TRUE.equals(forVpc)) {
+ services.add(NetworkACL.getName());
+ } else {
+ services.add(Firewall.getName());
+ }
+ return services;
+ }
+ }
+
+ public String getInternetProtocol() {
+ return internetProtocol;
+ }
+
+ public Boolean getSpecifyIpRanges() {
+ return specifyIpRanges == null ? false : specifyIpRanges;
+ }
+
+ public Boolean getConserveMode() {
+ if (conserveMode == null) {
+ return true;
+ }
+ return conserveMode;
+ }
+
+ public Boolean getIsPersistent() {
+ return isPersistent == null ? false : isPersistent;
+ }
+
+ public Boolean getForVpc() {
+ return forVpc;
+ }
+
+ public String getNetworkMode() {
+ return networkMode;
+ }
+
+ public boolean getNsxSupportsLbService() {
+ return BooleanUtils.isTrue(nsxSupportsLbService);
+ }
+
+ public boolean getNsxSupportsInternalLbService() {
+ return BooleanUtils.isTrue(nsxSupportsInternalLbService);
+ }
+
+ public Boolean getForTungsten() {
+ return forTungsten;
+ }
+
+ public Boolean getEgressDefaultPolicy() {
+ if (egressDefaultPolicy == null) {
+ return true;
+ }
+ return egressDefaultPolicy;
+ }
+
+ public Boolean getKeepAliveEnabled() {
+ return keepAliveEnabled;
+ }
+
+ public Integer getMaxconnections() {
+ return maxConnections;
+ }
+
+ public Map> getServiceProviders() {
+ Map> serviceProviderMap = new HashMap<>();
+ if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isExternalNetworkProvider()) {
+ Collection servicesCollection = serviceProviderList.values();
+ Iterator iter = servicesCollection.iterator();
+ while (iter.hasNext()) {
+ HashMap services = (HashMap) iter.next();
+ String service = services.get("service");
+ String provider = services.get("provider");
+ List providerList = null;
+ if (serviceProviderMap.containsKey(service)) {
+ providerList = serviceProviderMap.get(service);
+ } else {
+ providerList = new ArrayList();
+ }
+ providerList.add(provider);
+ serviceProviderMap.put(service, providerList);
+ }
+ } else if (isExternalNetworkProvider()) {
+ getServiceProviderMapForExternalProvider(serviceProviderMap, Network.Provider.getProvider(provider).getName());
+ }
+ return serviceProviderMap;
+ }
+
+ private void getServiceProviderMapForExternalProvider(Map> serviceProviderMap, String provider) {
+ String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() :
+ VirtualRouterProvider.Type.VirtualRouter.name();
+ List unsupportedServices = new ArrayList<>(List.of("Vpn", "Gateway", "SecurityGroup", "Connectivity", "BaremetalPxeService"));
+ List