Merge branch 'nsx-integration' of https://github.com/apache/cloudstack into nsx-cks-support

This commit is contained in:
Pearl Dsilva 2023-12-05 14:01:15 -05:00
commit 3a6f68b56a
344 changed files with 17921 additions and 1778 deletions

View File

@ -23,6 +23,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-22.04

View File

@ -23,6 +23,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
if: github.repository == 'apache/cloudstack'
@ -90,6 +93,7 @@ jobs:
smoke/test_nic
smoke/test_nic_adapter_type
smoke/test_non_contigiousvlan
smoke/test_object_stores
smoke/test_outofbandmanagement
smoke/test_outofbandmanagement_nestedplugin
smoke/test_over_provisioning
@ -108,7 +112,8 @@ jobs:
smoke/test_reset_configuration_settings
smoke/test_reset_vm_on_reboot
smoke/test_resource_accounting
smoke/test_resource_detail",
smoke/test_resource_detail
smoke/test_global_acls",
"smoke/test_router_dhcphosts
smoke/test_router_dns
smoke/test_router_dnsservice

View File

@ -23,6 +23,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-22.04

View File

@ -23,6 +23,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-22.04

View File

@ -10,10 +10,10 @@ This PR...
<!-- For addressing multiple issues/PRs, use multiple "Fixes: #<id>" -->
<!-- Fixes: # -->
<!--- ********************************************************************************* -->
<!--- NOTE: AUTOMATATION USES THE DESCRIPTIONS TO SET LABELS AND PRODUCE DOCUMENTATION. -->
<!--- ******************************************************************************* -->
<!--- NOTE: AUTOMATION USES THE DESCRIPTIONS TO SET LABELS AND PRODUCE DOCUMENTATION. -->
<!--- PLEASE PUT AN 'X' in only **ONE** box -->
<!--- ********************************************************************************* -->
<!--- ******************************************************************************* -->
### Types of changes

View File

@ -407,3 +407,15 @@ iscsi.session.cleanup.enabled=false
# The path of an executable file/script for host health check for CloudStack to Auto Disable/Enable the host
# depending on the return value of the file/script
# agent.health.check.script.path=
# Time interval (in milliseconds) between KVM heartbeats.
# kvm.heartbeat.update.frequency=60000
# Number of maximum tries to KVM heartbeats.
# kvm.heartbeat.update.max.tries=5
# Time amount (in milliseconds) for the KVM heartbeat retry sleep.
# kvm.heartbeat.update.retry.sleep=10000
# Timeout (in milliseconds) of the KVM heartbeat checker.
# kvm.heartbeat.checker.timeout=360000

View File

@ -92,11 +92,14 @@ public class PropertiesStorage implements StorageComponent {
file = new File(path);
try {
if (!file.createNewFile()) {
s_logger.error("Unable to create _file: " + file.getAbsolutePath());
s_logger.error(String.format("Unable to create _file: %s", file.getAbsolutePath()));
return false;
}
} catch (IOException e) {
s_logger.error("Unable to create _file: " + file.getAbsolutePath(), e);
s_logger.error(String.format("Unable to create file: %s", file.getAbsolutePath()));
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("IOException while trying to create file: %s", file.getAbsolutePath()), e);
}
return false;
}
}

View File

@ -539,10 +539,10 @@ public class AgentProperties{
/**
* Heartbeat update timeout (in ms).<br>
* Depending on the use case, this timeout might need increasing/decreasing.<br>
* Data type: Integer.<br>
* Default value: <code>60000</code>
* Data type: Long.<br>
* Default value: <code>60000L</code>
*/
public static final Property<Integer> HEARTBEAT_UPDATE_TIMEOUT = new Property<>("heartbeat.update.timeout", 60000);
public static final Property<Long> HEARTBEAT_UPDATE_TIMEOUT = new Property<>("heartbeat.update.timeout", 60000L);
/**
* The timeout (in seconds) to retrieve the target's domain ID when migrating a VM with KVM. <br>
@ -740,6 +740,38 @@ public class AgentProperties{
*/
public static final Property<String> CONTROL_CIDR = new Property<>("control.cidr", "169.254.0.0/16");
/**
* Time interval (in milliseconds) between KVM heartbeats. <br>
* This property is for KVM only.
* Data type: Long.<br>
* Default value: <code>60000l</code>
*/
public static final Property<Long> KVM_HEARTBEAT_UPDATE_FREQUENCY = new Property<>("kvm.heartbeat.update.frequency", 60000L);
/**
* Number of maximum tries to KVM heartbeats. <br>
* This property is for KVM only.
* Data type: Long.<br>
* Default value: <code>5l</code>
*/
public static final Property<Long> KVM_HEARTBEAT_UPDATE_MAX_TRIES = new Property<>("kvm.heartbeat.update.max.tries", 5L);
/**
* Time amount (in milliseconds) for the KVM heartbeat retry sleep. <br>
* This property is for KVM only.
* Data type: Long.<br>
* Default value: <code>10000l</code>
*/
public static final Property<Long> KVM_HEARTBEAT_UPDATE_RETRY_SLEEP = new Property<>("kvm.heartbeat.update.retry.sleep", 10000L);
/**
* Timeout (in milliseconds) of the KVM heartbeat checker. <br>
* This property is for KVM only.
* Data type: Long.<br>
* Default value: <code>360000l</code>
*/
public static final Property<Long> KVM_HEARTBEAT_CHECKER_TIMEOUT = new Property<>("kvm.heartbeat.checker.timeout", 360000L);
public static class Property <T>{
private String name;
private T defaultValue;

View File

@ -52,6 +52,13 @@ public class StoragePoolInfo {
this.details = details;
}
public StoragePoolInfo(String uuid, String host, String hostPath, String localPath, StoragePoolType poolType, long capacityBytes, long availableBytes,
Map<String, String> details, String name) {
this(uuid, host, hostPath, localPath, poolType, capacityBytes, availableBytes);
this.details = details;
this.name = name;
}
public long getCapacityBytes() {
return capacityBytes;
}

View File

@ -29,6 +29,8 @@ import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.ha.HAConfig;
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.cloudstack.usage.Usage;
import org.apache.cloudstack.vm.schedule.VMSchedule;
@ -714,6 +716,16 @@ public class EventTypes {
// SystemVM
public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM";
// OBJECT STORE
public static final String EVENT_OBJECT_STORE_CREATE = "OBJECT.STORE.CREATE";
public static final String EVENT_OBJECT_STORE_DELETE = "OBJECT.STORE.DELETE";
public static final String EVENT_OBJECT_STORE_UPDATE = "OBJECT.STORE.UPDATE";
// BUCKETS
public static final String EVENT_BUCKET_CREATE = "BUCKET.CREATE";
public static final String EVENT_BUCKET_DELETE = "BUCKET.DELETE";
public static final String EVENT_BUCKET_UPDATE = "BUCKET.UPDATE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@ -1151,6 +1163,16 @@ public class EventTypes {
entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class);
entityEventDetails.put(EVENT_IMAGE_STORE_OBJECT_DOWNLOAD, ImageStore.class);
entityEventDetails.put(EVENT_LIVE_PATCH_SYSTEMVM, "SystemVMs");
//Object Store
entityEventDetails.put(EVENT_OBJECT_STORE_CREATE, ObjectStore.class);
entityEventDetails.put(EVENT_OBJECT_STORE_UPDATE, ObjectStore.class);
entityEventDetails.put(EVENT_OBJECT_STORE_DELETE, ObjectStore.class);
//Buckets
entityEventDetails.put(EVENT_BUCKET_CREATE, Bucket.class);
entityEventDetails.put(EVENT_BUCKET_UPDATE, Bucket.class);
entityEventDetails.put(EVENT_BUCKET_DELETE, Bucket.class);
}
public static String getEntityForEvent(String eventName) {

View File

@ -25,6 +25,8 @@ import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd
import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd;
import org.apache.cloudstack.api.command.admin.network.ListGuestVlansCmd;
import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd;
import org.apache.cloudstack.api.command.user.address.RemoveQuarantinedIpCmd;
import org.apache.cloudstack.api.command.user.address.UpdateQuarantinedIpCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.CreateNetworkPermissionsCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworkPermissionsCmd;
@ -115,6 +117,8 @@ public interface NetworkService {
IpAddress getIp(long id);
IpAddress getIp(String ipAddress);
Network updateGuestNetwork(final UpdateNetworkCmd cmd);
/**
@ -249,4 +253,8 @@ public interface NetworkService {
boolean resetNetworkPermissions(ResetNetworkPermissionsCmd resetNetworkPermissionsCmd);
void validateIfServiceOfferingIsActiveAndSystemVmTypeIsDomainRouter(final Long serviceOfferingId) throws InvalidParameterValueException;
PublicIpQuarantine updatePublicIpAddressInQuarantine(UpdateQuarantinedIpCmd cmd);
void removePublicIpAddressFromQuarantine(RemoveQuarantinedIpCmd cmd);
}

View File

@ -0,0 +1,36 @@
// 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.network;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
public interface PublicIpQuarantine extends InternalIdentity, Identity {
Long getPublicIpAddressId();
Long getPreviousOwnerId();
Date getEndDate();
String getRemovalReason();
Date getRemoved();
Date getCreated();
}

View File

@ -68,7 +68,6 @@ public class VNF {
}
public enum VnfDetail {
ICON,
VERSION,
VENDOR,
MAINTAINER

View File

@ -30,7 +30,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
public enum ResourceObjectType {
UserVm(true, true, true),
Template(true, true, true),
VnfTemplate(true, true, true),
VnfTemplate(false, false, true),
ISO(true, false, true),
Volume(true, true),
Snapshot(true, false),
@ -69,7 +69,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
GuestOs(false, true),
NetworkOffering(false, true),
VpcOffering(true, false),
Domain(false, false, true);
Domain(false, false, true),
ObjectStore(false, false, true);
ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) {

View File

@ -21,7 +21,7 @@ package com.cloud.storage;
import com.cloud.utils.exception.CloudRuntimeException;
public enum DataStoreRole {
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup");
Primary("primary"), Image("image"), ImageCache("imagecache"), Backup("backup"), Object("object");
public boolean isImageStore() {
return (role.equalsIgnoreCase("image") || role.equalsIgnoreCase("imagecache")) ? true : false;
@ -45,6 +45,8 @@ public enum DataStoreRole {
return ImageCache;
} else if (role.equalsIgnoreCase("backup")) {
return Backup;
} else if (role.equalsIgnoreCase("object")) {
return Object;
} else {
throw new CloudRuntimeException("can't identify the role");
}

View File

@ -24,9 +24,11 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint
import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteObjectStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.UpdateObjectStoragePoolCmd;
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
import com.cloud.exception.DiscoveryException;
@ -34,6 +36,11 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.exception.ResourceUnavailableException;
import org.apache.cloudstack.api.command.admin.storage.heuristics.CreateSecondaryStorageSelectorCmd;
import org.apache.cloudstack.api.command.admin.storage.heuristics.RemoveSecondaryStorageSelectorCmd;
import org.apache.cloudstack.api.command.admin.storage.heuristics.UpdateSecondaryStorageSelectorCmd;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
import org.apache.cloudstack.storage.object.ObjectStore;
public interface StorageService {
/**
@ -109,4 +116,15 @@ public interface StorageService {
StoragePool syncStoragePool(SyncStoragePoolCmd cmd);
Heuristic createSecondaryStorageHeuristic(CreateSecondaryStorageSelectorCmd cmd);
Heuristic updateSecondaryStorageHeuristic(UpdateSecondaryStorageSelectorCmd cmd);
void removeSecondaryStorageHeuristic(RemoveSecondaryStorageSelectorCmd cmd);
ObjectStore discoverObjectStore(String name, String url, String providerName, Map details) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException;
boolean deleteObjectStore(DeleteObjectStoragePoolCmd cmd);
ObjectStore updateObjectStore(Long id, UpdateObjectStoragePoolCmd cmd);
}

View File

@ -45,7 +45,7 @@ public interface AnnotationService {
SERVICE_OFFERING(false), DISK_OFFERING(false), NETWORK_OFFERING(false),
ZONE(false), POD(false), CLUSTER(false), HOST(false), DOMAIN(false),
PRIMARY_STORAGE(false), SECONDARY_STORAGE(false), VR(false), SYSTEM_VM(false),
AUTOSCALE_VM_GROUP(true), MANAGEMENT_SERVER(false),;
AUTOSCALE_VM_GROUP(true), MANAGEMENT_SERVER(false), OBJECT_STORAGE(false);
private final boolean usersAllowed;
@ -78,6 +78,7 @@ public interface AnnotationService {
list.add(EntityType.VR);
list.add(EntityType.SYSTEM_VM);
list.add(EntityType.MANAGEMENT_SERVER);
list.add(EntityType.OBJECT_STORAGE);
if (roleType != RoleType.DomainAdmin) {
list.add(EntityType.DOMAIN);
list.add(EntityType.SERVICE_OFFERING);

View File

@ -78,7 +78,9 @@ public enum ApiCommandResourceType {
VmSnapshot(com.cloud.vm.snapshot.VMSnapshot.class),
Role(org.apache.cloudstack.acl.Role.class),
VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class),
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class);
ManagementServer(org.apache.cloudstack.management.ManagementServerHost.class),
ObjectStore(org.apache.cloudstack.storage.object.ObjectStore.class),
Bucket(org.apache.cloudstack.storage.object.Bucket.class);
private final Class<?> clazz;

View File

@ -224,6 +224,8 @@ public class ApiConstants {
public static final String INSTANCES_STATS_USER_ONLY = "instancesstatsuseronly";
public static final String PREFIX = "prefix";
public static final String PREVIOUS_ACL_RULE_ID = "previousaclruleid";
public static final String PREVIOUS_OWNER_ID = "previousownerid";
public static final String PREVIOUS_OWNER_NAME = "previousownername";
public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
public static final String IMAGE_PATH = "imagepath";
@ -404,6 +406,7 @@ public class ApiConstants {
public static final String SHOW_CAPACITIES = "showcapacities";
public static final String SHOW_REMOVED = "showremoved";
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 SIGNATURE = "signature";
public static final String SIGNATURE_VERSION = "signatureversion";
@ -802,6 +805,7 @@ public class ApiConstants {
public static final String IPSEC_PSK = "ipsecpsk";
public static final String GUEST_IP = "guestip";
public static final String REMOVED = "removed";
public static final String REMOVAL_REASON = "removalreason";
public static final String COMPLETED = "completed";
public static final String IKE_VERSION = "ikeversion";
public static final String IKE_POLICY = "ikepolicy";
@ -1059,11 +1063,20 @@ public class ApiConstants {
public static final String MTU = "mtu";
public static final String AUTO_ENABLE_KVM_HOST = "autoenablekvmhost";
public static final String LIST_APIS = "listApis";
public static final String OBJECT_STORAGE_ID = "objectstorageid";
public static final String VERSIONING = "versioning";
public static final String OBJECT_LOCKING = "objectlocking";
public static final String ENCRYPTION = "encryption";
public static final String QUOTA = "quota";
public static final String ACCESS_KEY = "accesskey";
public static final String SOURCE_NAT_IP = "sourcenatipaddress";
public static final String SOURCE_NAT_IP_ID = "sourcenatipaddressid";
public static final String HAS_RULES = "hasrules";
public static final String NSX_DETAIL_KEY = "forNsx";
public static final String OBJECT_STORAGE = "objectstore";
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 MANAGEMENT = "management";
public static final String IS_VNF = "isvnf";
public static final String VNF_NICS = "vnfnics";
@ -1076,6 +1089,10 @@ public class ApiConstants {
public static final String CLIENT_ID = "clientid";
public static final String REDIRECT_URI = "redirecturi";
public static final String IS_TAG_A_RULE = "istagarule";
public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not.";
/**
* 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).

View File

@ -42,6 +42,7 @@ import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
import org.apache.cloudstack.query.QueryService;
import org.apache.cloudstack.storage.object.BucketApiService;
import org.apache.cloudstack.storage.ImageStoreService;
import org.apache.cloudstack.storage.template.VnfTemplateManager;
import org.apache.cloudstack.usage.UsageService;
@ -216,6 +217,9 @@ public abstract class BaseCmd {
public Ipv6Service ipv6Service;
@Inject
public VnfTemplateManager vnfTemplateManager;
@Inject
public BucketApiService _bucketService;
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException, NetworkRuleConflictException;

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.cloudstack.affinity.AffinityGroup;
import org.apache.cloudstack.affinity.AffinityGroupResponse;
import org.apache.cloudstack.api.ApiConstants.HostDetails;
@ -37,6 +38,7 @@ import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
import org.apache.cloudstack.api.response.BackupOfferingResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.BackupScheduleResponse;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConditionResponse;
@ -64,6 +66,7 @@ import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
import org.apache.cloudstack.api.response.HypervisorGuestOsNamesResponse;
import org.apache.cloudstack.api.response.IPAddressResponse;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.InternalLoadBalancerElementResponse;
@ -81,6 +84,7 @@ import org.apache.cloudstack.api.response.NetworkPermissionsResponse;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.apache.cloudstack.api.response.NicResponse;
import org.apache.cloudstack.api.response.NicSecondaryIpResponse;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.cloudstack.api.response.OvsProviderResponse;
import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
import org.apache.cloudstack.api.response.PodResponse;
@ -100,6 +104,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.ServiceResponse;
@ -144,6 +149,8 @@ import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.cloudstack.usage.Usage;
import com.cloud.capacity.Capacity;
@ -169,6 +176,7 @@ import com.cloud.network.OvsProvider;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PhysicalNetworkTrafficType;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.RouterHealthCheckResult;
import com.cloud.network.Site2SiteCustomerGateway;
@ -529,4 +537,12 @@ public interface ResponseGenerator {
DirectDownloadCertificateHostStatusResponse createDirectDownloadCertificateProvisionResponse(Long certificateId, Long hostId, Pair<Boolean, String> result);
FirewallResponse createIpv6FirewallRuleResponse(FirewallRule acl);
SecondaryStorageHeuristicsResponse createSecondaryStorageSelectorResponse(Heuristic heuristic);
IpQuarantineResponse createQuarantinedIpsResponse(PublicIpQuarantine publicIp);
ObjectStoreResponse createObjectStoreResponse(ObjectStore os);
BucketResponse createBucketResponse(Bucket bucket);
}

View File

@ -119,6 +119,10 @@ public class ListHostsCmd extends BaseListCmd {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getHostName() {
return hostName;
}

View File

@ -60,6 +60,9 @@ public class UpdateHostCmd extends BaseCmd {
@Parameter(name = ApiConstants.HOST_TAGS, type = CommandType.LIST, collectionType = CommandType.STRING, description = "list of tags to be added to the host")
private List<String> hostTags;
@Parameter(name = ApiConstants.IS_TAG_A_RULE, type = CommandType.BOOLEAN, description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, description = "the new uri for the secondary storage: nfs://host/path")
private String url;
@ -90,6 +93,10 @@ public class UpdateHostCmd extends BaseCmd {
return hostTags;
}
public Boolean getIsTagARule() {
return isTagARule;
}
public String getUrl() {
return url;
}

View File

@ -0,0 +1,132 @@
// 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.storage;
import org.apache.cloudstack.storage.object.ObjectStore;
import com.cloud.user.Account;
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.ObjectStoreResponse;
import org.apache.log4j.Logger;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@APICommand(name = "addObjectStoragePool", description = "Adds a object storage pool", responseObject = ObjectStoreResponse.class, since = "4.19.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class AddObjectStoragePoolCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AddObjectStoragePoolCmd.class.getName());
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name for the object store")
private String name;
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, length = 2048, required = true, description = "the URL for the object store")
private String url;
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, required = true, description = "the object store provider name")
private String providerName;
@Parameter(name = ApiConstants.DETAILS,
type = CommandType.MAP,
description = "the details for the object store. Example: details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss")
private Map details;
@Parameter(name = ApiConstants.TAGS, type = CommandType.STRING, description = "the tags for the storage pool")
private String tags;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getUrl() {
return url;
}
public String getName() {
return name;
}
public Map<String, String> getDetails() {
Map<String, String> detailsMap = null;
if (details != null && !details.isEmpty()) {
detailsMap = new HashMap<String, String>();
Collection<?> props = details.values();
Iterator<?> iter = props.iterator();
while (iter.hasNext()) {
HashMap<String, String> detail = (HashMap<String, String>)iter.next();
String key = detail.get(ApiConstants.KEY);
String value = detail.get(ApiConstants.VALUE);
detailsMap.put(key, value);
}
}
return detailsMap;
}
public String getProviderName() {
return providerName;
}
public void setUrl(String url) {
this.url = url;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public void setDetails(Map<String, String> details) {
this.details = details;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
try{
ObjectStore result = _storageService.discoverObjectStore(getName(), getUrl(), getProviderName(), getDetails());
ObjectStoreResponse storeResponse = null;
if (result != null) {
storeResponse = _responseGenerator.createObjectStoreResponse(result);
storeResponse.setResponseName(getCommandName());
storeResponse.setObjectName("objectstore");
setResponseObject(storeResponse);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add object storage");
}
} catch (Exception ex) {
s_logger.error("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
}
}

View File

@ -90,6 +90,9 @@ public class CreateStoragePoolCmd extends BaseCmd {
description = "hypervisor type of the hosts in zone that will be attached to this storage pool. KVM, VMware supported as of now.")
private String hypervisor;
@Parameter(name = ApiConstants.IS_TAG_A_RULE, type = CommandType.BOOLEAN, description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -146,6 +149,10 @@ public class CreateStoragePoolCmd extends BaseCmd {
return hypervisor;
}
public Boolean isTagARule() {
return this.isTagARule;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;

View File

@ -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
// 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.storage;
import com.cloud.user.Account;
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.ObjectStoreResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.log4j.Logger;
@APICommand(name = "deleteObjectStoragePool", description = "Deletes an Object Storage Pool", responseObject = SuccessResponse.class, since = "4.19.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteObjectStoragePoolCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteObjectStoragePoolCmd.class.getName());
// ///////////////////////////////////////////////////
// ////////////// API parameters /////////////////////
// ///////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, required = true, description = "The Object Storage ID.")
private Long id;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
public Long getId() {
return id;
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute() {
boolean result = _storageService.deleteObjectStore(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete object store");
}
}
}

View File

@ -0,0 +1,79 @@
// 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.storage;
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.response.ListResponse;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.log4j.Logger;
@APICommand(name = "listObjectStoragePools", description = "Lists object storage pools.", responseObject = ObjectStoreResponse.class, since = "4.19.0",
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListObjectStoragePoolsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListObjectStoragePoolsCmd.class.getName());
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the object store")
private String storeName;
@Parameter(name = ApiConstants.PROVIDER, type = CommandType.STRING, description = "the object store provider")
private String provider;
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, description = "the ID of the storage pool")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getStoreName() {
return storeName;
}
public Long getId() {
return id;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
ListResponse<ObjectStoreResponse> response = _queryService.searchForObjectStores(this);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -24,6 +24,7 @@ import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PodResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
@ -63,16 +64,25 @@ public class ListStoragePoolsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, description = "the ID of the storage pool")
private Long id;
@Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the ID of the storage pool")
@Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the scope of the storage pool")
private String scope;
@Parameter(name = ApiConstants.STATUS, type = CommandType.STRING, description = "the status of the storage pool")
private String status;
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "host ID of the storage pools")
private Long hostId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getHostId() {
return hostId;
}
public Long getClusterId() {
return clusterId;
}
@ -81,6 +91,10 @@ public class ListStoragePoolsCmd extends BaseListCmd {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getStoragePoolName() {
return storagePoolName;
}
@ -108,6 +122,15 @@ public class ListStoragePoolsCmd extends BaseListCmd {
public void setId(Long id) {
this.id = id;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -123,8 +146,4 @@ public class ListStoragePoolsCmd extends BaseListCmd {
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
public String getScope() {
return scope;
}
}

View File

@ -0,0 +1,93 @@
// 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.storage;
import org.apache.cloudstack.storage.object.ObjectStore;
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.ObjectStoreResponse;
import org.apache.cloudstack.context.CallContext;
@APICommand(name = UpdateObjectStoragePoolCmd.APINAME, description = "Updates object storage pool", responseObject = ObjectStoreResponse.class, entityType = {ObjectStore.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0")
public class UpdateObjectStoragePoolCmd extends BaseCmd {
public static final String APINAME = "updateObjectStoragePool";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ObjectStoreResponse.class, required = true, description = "Object Store ID")
private Long id;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name for the object store")
private String name;
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, description = "the url for the object store")
private String url;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getUrl() {
return url;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
ObjectStore result = _storageService.updateObjectStore(getId(), this);
ObjectStoreResponse storeResponse = null;
if (result != null) {
storeResponse = _responseGenerator.createObjectStoreResponse(result);
storeResponse.setResponseName(getCommandName());
storeResponse.setObjectName("objectstore");
setResponseObject(storeResponse);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update object storage");
}
}
@Override
public String getCommandName() {
return APINAME;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
}

View File

@ -61,6 +61,9 @@ public class UpdateStoragePoolCmd extends BaseCmd {
" enable it back.")
private Boolean enabled;
@Parameter(name = ApiConstants.IS_TAG_A_RULE, type = CommandType.BOOLEAN, description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -89,6 +92,10 @@ public class UpdateStoragePoolCmd extends BaseCmd {
return enabled;
}
public Boolean isTagARule() {
return isTagARule;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -0,0 +1,93 @@
// 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.storage.heuristics;
import com.cloud.user.Account;
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.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
import static org.apache.cloudstack.api.ApiConstants.HEURISTIC_TYPE_VALID_OPTIONS;
@APICommand(name = "createSecondaryStorageSelector", description = "Creates a secondary storage selector, described by the heuristic rule.", since = "4.19.0", responseObject =
SecondaryStorageHeuristicsResponse.class, entityType = {Heuristic.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
public class CreateSecondaryStorageSelectorCmd extends BaseCmd{
@Parameter(name = ApiConstants.NAME, required = true, type = CommandType.STRING, description = "The name identifying the heuristic rule.")
private String name;
@Parameter(name = ApiConstants.DESCRIPTION, required = true, type = BaseCmd.CommandType.STRING, description = "The description of the heuristic rule.")
private String description;
@Parameter(name = ApiConstants.ZONE_ID, required = true, entityType = ZoneResponse.class, type = BaseCmd.CommandType.UUID, description = "The zone in which the heuristic " +
"rule will be applied.")
private Long zoneId;
@Parameter(name = ApiConstants.TYPE, required = true, type = BaseCmd.CommandType.STRING, description =
"The resource type directed to a specific secondary storage by the selector. " + HEURISTIC_TYPE_VALID_OPTIONS)
private String type;
@Parameter(name = ApiConstants.HEURISTIC_RULE, required = true, type = BaseCmd.CommandType.STRING, description = "The heuristic rule, in JavaScript language. It is required " +
"that it returns the UUID of a secondary storage pool. An example of a rule is `if (snapshot.hypervisorType === 'KVM') { '7832f261-c602-4e8e-8580-2496ffbbc45d'; " +
"}` would allocate all snapshots with the KVM hypervisor to the specified secondary storage UUID.", length = 65535)
private String heuristicRule;
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public Long getZoneId() {
return zoneId;
}
public String getType() {
return type;
}
public String getHeuristicRule() {
return heuristicRule;
}
@Override
public void execute() {
Heuristic heuristic = _storageService.createSecondaryStorageHeuristic(this);
if (heuristic == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a secondary storage selector.");
}
SecondaryStorageHeuristicsResponse response = _responseGenerator.createSecondaryStorageSelectorResponse(heuristic);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -0,0 +1,63 @@
// 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.storage.heuristics;
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.response.ListResponse;
import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
import static org.apache.cloudstack.api.ApiConstants.HEURISTIC_TYPE_VALID_OPTIONS;
@APICommand(name = "listSecondaryStorageSelectors", description = "Lists the secondary storage selectors and their rules.", since = "4.19.0", responseObject =
SecondaryStorageHeuristicsResponse.class, requestHasSensitiveInfo = false, entityType = {Heuristic.class}, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
public class ListSecondaryStorageSelectorsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.ZONE_ID, required = true, entityType = ZoneResponse.class, type = CommandType.UUID, description = "The zone ID to be used in the search filter.")
private Long zoneId;
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description =
"Whether to filter the selectors by type and, if so, which one. " + HEURISTIC_TYPE_VALID_OPTIONS)
private String type;
@Parameter(name = ApiConstants.SHOW_REMOVED, type = CommandType.BOOLEAN, description = "Show removed heuristics.")
private boolean showRemoved = false;
public Long getZoneId() {
return zoneId;
}
public String getType() {
return type;
}
public boolean isShowRemoved() {
return showRemoved;
}
@Override
public void execute() {
ListResponse<SecondaryStorageHeuristicsResponse> response = _queryService.listSecondaryStorageSelectors(this);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,54 @@
// 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.storage.heuristics;
import com.cloud.user.Account;
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.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
@APICommand(name = "removeSecondaryStorageSelector", description = "Removes an existing secondary storage selector.", since = "4.19.0", responseObject =
SecondaryStorageHeuristicsResponse.class, requestHasSensitiveInfo = false, entityType = {Heuristic.class}, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
public class RemoveSecondaryStorageSelectorCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = SecondaryStorageHeuristicsResponse.class, required = true,
description = "The unique identifier of the secondary storage selector to be removed.")
private Long id;
public Long getId() {
return id;
}
@Override
public void execute() {
_storageService.removeSecondaryStorageHeuristic(this);
final SuccessResponse response = new SuccessResponse();
response.setResponseName(getCommandName());
response.setSuccess(true);
setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -0,0 +1,67 @@
// 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.storage.heuristics;
import com.cloud.user.Account;
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.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
@APICommand(name = "updateSecondaryStorageSelector", description = "Updates an existing secondary storage selector.", since = "4.19.0", responseObject =
SecondaryStorageHeuristicsResponse.class, requestHasSensitiveInfo = false, entityType = {Heuristic.class}, responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
public class UpdateSecondaryStorageSelectorCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = SecondaryStorageHeuristicsResponse.class, required = true,
description = "The unique identifier of the secondary storage selector.")
private Long id;
@Parameter(name = ApiConstants.HEURISTIC_RULE, required = true, type = BaseCmd.CommandType.STRING, description = "The heuristic rule, in JavaScript language. It is required " +
"that it returns the UUID of a secondary storage pool. An example of a rule is `if (snapshot.hypervisorType === 'KVM') { '7832f261-c602-4e8e-8580-2496ffbbc45d'; " +
"}` would allocate all snapshots with the KVM hypervisor to the specified secondary storage UUID.", length = 65535)
private String heuristicRule;
public Long getId() {
return id;
}
public String getHeuristicRule() {
return heuristicRule;
}
@Override
public void execute() {
Heuristic heuristic = _storageService.updateSecondaryStorageHeuristic(this);
if (heuristic == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update the secondary storage selector.");
}
SecondaryStorageHeuristicsResponse response = _responseGenerator.createSecondaryStorageSelectorResponse(heuristic);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -46,10 +46,14 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IPAddressResponse.class, required = true, description = "the ID of the public IP address"
+ " to disassociate")
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IPAddressResponse.class, description = "the ID of the public IP address"
+ " to disassociate. Mutually exclusive with the ipaddress parameter")
private Long id;
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, since="4.19.0", description="IP Address to be disassociated."
+ " Mutually exclusive with the id parameter")
private String ipAddress;
// unexposed parameter needed for events logging
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, expose = false)
private Long ownerId;
@ -59,7 +63,18 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
public Long getIpAddressId() {
return id;
if (id != null & ipAddress != null) {
throw new InvalidParameterValueException("id parameter is mutually exclusive with ipaddress parameter");
}
if (id != null) {
return id;
} else if (ipAddress != null) {
IpAddress ip = getIpAddressByIp(ipAddress);
return ip.getId();
}
throw new InvalidParameterValueException("Please specify either IP address or IP address ID");
}
/////////////////////////////////////////////////////
@ -68,12 +83,13 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
@Override
public void execute() throws InsufficientAddressCapacityException {
CallContext.current().setEventDetails("IP ID: " + getIpAddressId());
Long ipAddressId = getIpAddressId();
CallContext.current().setEventDetails("IP ID: " + ipAddressId);
boolean result = false;
if (!isPortable(id)) {
result = _networkService.releaseIpAddress(getIpAddressId());
if (!isPortable()) {
result = _networkService.releaseIpAddress(ipAddressId);
} else {
result = _networkService.releasePortableIpAddress(getIpAddressId());
result = _networkService.releasePortableIpAddress(ipAddressId);
}
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
@ -85,7 +101,7 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
@Override
public String getEventType() {
if (!isPortable(id)) {
if (!isPortable()) {
return EventTypes.EVENT_NET_IP_RELEASE;
} else {
return EventTypes.EVENT_PORTABLE_IP_RELEASE;
@ -100,10 +116,7 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
@Override
public long getEntityOwnerId() {
if (ownerId == null) {
IpAddress ip = getIpAddress(id);
if (ip == null) {
throw new InvalidParameterValueException("Unable to find IP address by ID=" + id);
}
IpAddress ip = getIpAddress();
ownerId = ip.getAccountId();
}
@ -120,11 +133,11 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
@Override
public Long getSyncObjId() {
IpAddress ip = getIpAddress(id);
IpAddress ip = getIpAddress();
return ip.getAssociatedWithNetworkId();
}
private IpAddress getIpAddress(long id) {
private IpAddress getIpAddressById(Long id) {
IpAddress ip = _entityMgr.findById(IpAddress.class, id);
if (ip == null) {
@ -134,6 +147,29 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
}
}
private IpAddress getIpAddressByIp(String ipAddress) {
IpAddress ip = _networkService.getIp(ipAddress);
if (ip == null) {
throw new InvalidParameterValueException("Unable to find IP address by IP address=" + ipAddress);
} else {
return ip;
}
}
private IpAddress getIpAddress() {
if (id != null & ipAddress != null) {
throw new InvalidParameterValueException("id parameter is mutually exclusive with ipaddress parameter");
}
if (id != null) {
return getIpAddressById(id);
} else if (ipAddress != null){
return getIpAddressByIp(ipAddress);
}
throw new InvalidParameterValueException("Please specify either IP address or IP address ID");
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.IpAddress;
@ -144,8 +180,8 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd {
return getIpAddressId();
}
private boolean isPortable(long id) {
IpAddress ip = getIpAddress(id);
private boolean isPortable() {
IpAddress ip = getIpAddress();
return ip.isPortable();
}
}

View File

@ -0,0 +1,51 @@
// 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.user.address;
import com.cloud.network.PublicIpQuarantine;
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.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.ListResponse;
@APICommand(name = "listQuarantinedIps", responseObject = IpQuarantineResponse.class, description = "List public IP addresses in quarantine.", since = "4.19",
entityType = {PublicIpQuarantine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin, RoleType.DomainAdmin})
public class ListQuarantinedIpsCmd extends BaseListCmd {
@Parameter(name = ApiConstants.SHOW_REMOVED, type = CommandType.BOOLEAN, description = "Show IPs removed from quarantine.")
private boolean showRemoved = false;
@Parameter(name = ApiConstants.SHOW_INACTIVE, type = CommandType.BOOLEAN, description = "Show IPs that are no longer in quarantine.")
private boolean showInactive = false;
public boolean isShowRemoved() {
return showRemoved;
}
public boolean isShowInactive() {
return showInactive;
}
@Override
public void execute() {
ListResponse<IpQuarantineResponse> response = _queryService.listQuarantinedIps(this);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,72 @@
// 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.user.address;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.user.Account;
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.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
@APICommand(name = "removeQuarantinedIp", responseObject = IpQuarantineResponse.class, description = "Removes a public IP address from quarantine. Only IPs in active " +
"quarantine can be removed.",
since = "4.19", entityType = {PublicIpQuarantine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
authorized = {RoleType.Admin, RoleType.DomainAdmin})
public class RemoveQuarantinedIpCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IpQuarantineResponse.class, description = "The ID of the public IP address in active quarantine. " +
"Either the IP address is informed, or the ID of the IP address in quarantine.")
private Long id;
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "The public IP address in active quarantine. Either the IP address is informed, or the ID" +
" of the IP address in quarantine.")
private String ipAddress;
@Parameter(name = ApiConstants.REMOVAL_REASON, type = CommandType.STRING, required = true, description = "The reason for removing the public IP address from quarantine " +
"prematurely.")
private String removalReason;
public Long getId() {
return id;
}
public String getIpAddress() {
return ipAddress;
}
public String getRemovalReason() {
return removalReason;
}
@Override
public void execute() {
_networkService.removePublicIpAddressFromQuarantine(this);
final SuccessResponse response = new SuccessResponse();
response.setResponseName(getCommandName());
response.setSuccess(true);
setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -0,0 +1,75 @@
// 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.user.address;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.user.Account;
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.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
import java.util.Date;
@APICommand(name = "updateQuarantinedIp", responseObject = IpQuarantineResponse.class, description = "Updates the quarantine end date for the given public IP address.",
since = "4.19", entityType = {PublicIpQuarantine.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
authorized = {RoleType.Admin, RoleType.DomainAdmin})
public class UpdateQuarantinedIpCmd extends BaseCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = IpQuarantineResponse.class, description = "The ID of the public IP address in " +
"active quarantine.")
private Long id;
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "The public IP address in active quarantine. Either the IP address is informed, or the ID" +
" of the IP address in quarantine.")
private String ipAddress;
@Parameter(name = ApiConstants.END_DATE, type = BaseCmd.CommandType.DATE, required = true, description = "The date when the quarantine will no longer be active.")
private Date endDate;
public Long getId() {
return id;
}
public String getIpAddress() {
return ipAddress;
}
public Date getEndDate() {
return endDate;
}
@Override
public void execute() {
PublicIpQuarantine publicIpQuarantine = _networkService.updatePublicIpAddressInQuarantine(this);
if (publicIpQuarantine == null) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update public IP quarantine.");
}
IpQuarantineResponse response = _responseGenerator.createQuarantinedIpsResponse(publicIpQuarantine);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
}

View File

@ -0,0 +1,202 @@
// 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.user.bucket;
import com.cloud.event.EventTypes;
import com.cloud.exception.ResourceAllocationException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.storage.object.Bucket;
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.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.UserCmd;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
@APICommand(name = "createBucket", responseObject = BucketResponse.class,
description = "Creates a bucket in the specified object storage pool. ", responseView = ResponseView.Restricted,
entityType = {Bucket.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class CreateBucketCmd extends BaseAsyncCreateCmd implements UserCmd {
public static final Logger s_logger = Logger.getLogger(CreateBucketCmd.class.getName());
private static final String s_name = "createbucketresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ACCOUNT,
type = CommandType.STRING,
description = "the account associated with the bucket. Must be used with the domainId parameter.")
private String accountName;
@Parameter(name = ApiConstants.PROJECT_ID,
type = CommandType.UUID,
entityType = ProjectResponse.class,
description = "the project associated with the bucket. Mutually exclusive with account parameter")
private Long projectId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
description = "the domain ID associated with the bucket. If used with the account parameter"
+ " returns the bucket associated with the account for the specified domain.")
private Long domainId;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true,description = "the name of the bucket")
private String bucketName;
@Parameter(name = ApiConstants.OBJECT_STORAGE_ID, type = CommandType.UUID,
entityType = ObjectStoreResponse.class, required = true,
description = "Id of the Object Storage Pool where bucket is created")
private long objectStoragePoolId;
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
private Integer quota;
@Parameter(name = ApiConstants.ENCRYPTION, type = CommandType.BOOLEAN, description = "Enable bucket encryption")
private boolean encryption;
@Parameter(name = ApiConstants.VERSIONING, type = CommandType.BOOLEAN, description = "Enable bucket versioning")
private boolean versioning;
@Parameter(name = ApiConstants.OBJECT_LOCKING, type = CommandType.BOOLEAN, description = "Enable object locking in bucket")
private boolean objectLocking;
@Parameter(name = ApiConstants.POLICY, type = CommandType.STRING,description = "The Bucket access policy")
private String policy;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getAccountName() {
return accountName;
}
public Long getDomainId() {
return domainId;
}
public String getBucketName() {
return bucketName;
}
private Long getProjectId() {
return projectId;
}
public long getObjectStoragePoolId() {
return objectStoragePoolId;
}
public Integer getQuota() {
return quota;
}
public boolean isEncryption() {
return encryption;
}
public boolean isVersioning() {
return versioning;
}
public boolean isObjectLocking() {
return objectLocking;
}
public String getPolicy() {
return policy;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
public static String getResultObjectName() {
return "bucket";
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.Bucket;
}
@Override
public long getEntityOwnerId() {
Long accountId = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
if (accountId == null) {
return CallContext.current().getCallingAccount().getId();
}
return accountId;
}
@Override
public String getEventType() {
return EventTypes.EVENT_BUCKET_CREATE;
}
@Override
public String getEventDescription() {
return "creating bucket: " + getBucketName();
}
@Override
public void create() throws ResourceAllocationException {
Bucket bucket = _bucketService.allocBucket(this);
if (bucket != null) {
setEntityId(bucket.getId());
setEntityUuid(bucket.getUuid());
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create bucket");
}
}
@Override
public void execute() {
CallContext.current().setEventDetails("Bucket Id: " + getEntityUuid());
Bucket bucket;
try {
bucket = _bucketService.createBucket(this);
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
if (bucket != null) {
BucketResponse response = _responseGenerator.createBucketResponse(bucket);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create bucket with name: "+getBucketName());
}
}
}

View File

@ -0,0 +1,94 @@
// 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.user.bucket;
import com.cloud.exception.ConcurrentOperationException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.storage.object.Bucket;
import com.cloud.user.Account;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ACL;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
@APICommand(name = "deleteBucket", description = "Deletes an empty Bucket.", responseObject = SuccessResponse.class, entityType = {Bucket.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class DeleteBucketCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteBucketCmd.class.getName());
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=BucketResponse.class,
required=true, description="The ID of the Bucket")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public static String getResultObjectName() {
return "bucket";
}
@Override
public long getEntityOwnerId() {
Bucket Bucket = _entityMgr.findById(Bucket.class, getId());
if (Bucket != null) {
return Bucket.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public Long getApiResourceId() {
return id;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.Bucket;
}
@Override
public void execute() throws ConcurrentOperationException {
CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId()));
boolean result = _bucketService.deleteBucket(id, CallContext.current().getCallingAccount());
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
setResponseObject(response);
}
}

View File

@ -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
// 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.user.bucket;
import org.apache.cloudstack.storage.object.Bucket;
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.BaseListTaggedResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.UserCmd;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.log4j.Logger;
import java.util.List;
@APICommand(name = "listBuckets", description = "Lists all Buckets.", responseObject = BucketResponse.class, responseView = ResponseView.Restricted, entityType = {
Bucket.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListBucketsCmd extends BaseListTaggedResourcesCmd implements UserCmd {
public static final Logger s_logger = Logger.getLogger(ListBucketsCmd.class.getName());
private static final String s_name = "listbucketsresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = BucketResponse.class, description = "the ID of the bucket")
private Long id;
@Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = BucketResponse.class, description = "the IDs of the Buckets, mutually exclusive with id")
private List<Long> ids;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "the name of the bucket")
private String bucketName;
@Parameter(name = ApiConstants.OBJECT_STORAGE_ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, description = "the ID of the object storage pool, available to ROOT admin only", authorized = {
RoleType.Admin})
private Long objectStorageId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public String getBucketName() {
return bucketName;
}
public Long getObjectStorageId() {
return objectStorageId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.Bucket;
}
@Override
public void execute() {
ListResponse<BucketResponse> response = _queryService.searchForBuckets(this);
response.setResponseName(getCommandName());
setResponseObject(response);
}
public List<Long> getIds() {
return ids;
}
}

View File

@ -0,0 +1,132 @@
// 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.user.bucket;
import com.cloud.exception.ConcurrentOperationException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.storage.object.Bucket;
import com.cloud.user.Account;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.ACL;
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.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
@APICommand(name = "updateBucket", description = "Updates Bucket properties", responseObject = SuccessResponse.class, entityType = {Bucket.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.19.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class UpdateBucketCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(UpdateBucketCmd.class.getName());
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@ACL(accessType = AccessType.OperateEntry)
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=BucketResponse.class,
required=true, description="The ID of the Bucket")
private Long id;
@Parameter(name = ApiConstants.VERSIONING, type = CommandType.BOOLEAN, description = "Enable/Disable Bucket Versioning")
private Boolean versioning;
@Parameter(name = ApiConstants.ENCRYPTION, type = CommandType.BOOLEAN, description = "Enable/Disable Bucket encryption")
private Boolean encryption;
@Parameter(name = ApiConstants.POLICY, type = CommandType.STRING, description = "Bucket Access Policy")
private String policy;
@Parameter(name = ApiConstants.QUOTA, type = CommandType.INTEGER,description = "Bucket Quota in GB")
private Integer quota;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
public Boolean getVersioning() {
return versioning;
}
public Boolean getEncryption() {
return encryption;
}
public String getPolicy() {
return policy;
}
public Integer getQuota() {
return quota;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
public static String getResultObjectName() {
return "bucket";
}
@Override
public long getEntityOwnerId() {
Bucket Bucket = _entityMgr.findById(Bucket.class, getId());
if (Bucket != null) {
return Bucket.getAccountId();
}
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@Override
public Long getApiResourceId() {
return id;
}
@Override
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.Bucket;
}
@Override
public void execute() throws ConcurrentOperationException {
CallContext.current().setEventDetails("Bucket Id: " + this._uuidMgr.getUuid(Bucket.class, getId()));
boolean result = false;
try {
result = _bucketService.updateBucket(this, CallContext.current().getCallingAccount());
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Error while updating bucket. "+e.getMessage());
}
if(result) {
SuccessResponse response = new SuccessResponse(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update bucket");
}
}
}

View File

@ -29,6 +29,7 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@ -54,7 +55,6 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
@Parameter(name = ApiConstants.DISPLAY_TEXT,
type = BaseCmd.CommandType.STRING,
required = true,
description = "the display text of the ISO. This is usually used for display purposes.",
length = 4096)
private String displayText;
@ -85,7 +85,7 @@ public class GetUploadParamsForIsoCmd extends AbstractGetUploadParamsCmd {
}
public String getDisplayText() {
return displayText;
return StringUtils.isBlank(displayText) ? getName() : displayText;
}
public Boolean isFeatured() {

View File

@ -177,6 +177,9 @@ public class RegisterIsoCmd extends BaseCmd implements UserCmd {
}
public Long getZoneId() {
if (zoneId == null || zoneId == -1) {
return null;
}
return zoneId;
}
@ -220,6 +223,10 @@ public class RegisterIsoCmd extends BaseCmd implements UserCmd {
return directDownload == null ? false : directDownload;
}
public void setDirectDownload(Boolean directDownload) {
this.directDownload = directDownload;
}
public boolean isPasswordEnabled() {
return passwordEnabled == null ? false : passwordEnabled;
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.network;
import com.cloud.exception.PermissionDeniedException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
@ -26,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.NetworkACLResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
@ -35,7 +37,8 @@ import com.cloud.network.vpc.NetworkACL;
import com.cloud.network.vpc.Vpc;
import com.cloud.user.Account;
@APICommand(name = "createNetworkACLList", description = "Creates a network ACL for the given VPC", responseObject = NetworkACLResponse.class,
@APICommand(name = "createNetworkACLList", description = "Creates a network ACL. If no VPC is given, then it creates a global ACL that can be used by everyone.",
responseObject = NetworkACLResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreateNetworkACLListCmd.class.getName());
@ -53,7 +56,6 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
@Parameter(name = ApiConstants.VPC_ID,
type = CommandType.UUID,
required = true,
entityType = VpcResponse.class,
description = "ID of the VPC associated with this network ACL list")
private Long vpcId;
@ -77,6 +79,10 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
return vpcId;
}
public void setVpcId(Long vpcId) {
this.vpcId = vpcId;
}
@Override
public boolean isDisplay() {
if (display != null) {
@ -92,6 +98,9 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
@Override
public void create() {
if (getVpcId() == null) {
setVpcId(0L);
}
NetworkACL result = _networkACLService.createNetworkACL(getName(), getDescription(), getVpcId(), isDisplay());
setEntityId(result.getId());
setEntityUuid(result.getUuid());
@ -111,12 +120,21 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
@Override
public long getEntityOwnerId() {
Vpc vpc = _entityMgr.findById(Vpc.class, getVpcId());
if (vpc == null) {
throw new InvalidParameterValueException("Invalid vpcId is given");
}
Account account;
if (isAclAttachedToVpc(this.vpcId)) {
Vpc vpc = _entityMgr.findById(Vpc.class, this.vpcId);
if (vpc == null) {
throw new InvalidParameterValueException(String.format("Invalid VPC ID [%s] provided.", this.vpcId));
}
account = _accountService.getAccount(vpc.getAccountId());
} else {
account = CallContext.current().getCallingAccount();
if (!Account.Type.ADMIN.equals(account.getType())) {
s_logger.warn(String.format("Only Root Admin can create global ACLs. Account [%s] cannot create any global ACL.", account));
throw new PermissionDeniedException("Only Root Admin can create global ACLs.");
}
Account account = _accountService.getAccount(vpc.getAccountId());
}
return account.getId();
}
@ -139,4 +157,8 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
public ApiCommandResourceType getApiResourceType() {
return ApiCommandResourceType.NetworkAcl;
}
public boolean isAclAttachedToVpc(Long aclVpcId) {
return aclVpcId != null && aclVpcId != 0;
}
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.offering;
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
@ -23,14 +24,14 @@ import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.ListResponse;
@APICommand(name = "listDiskOfferings", description = "Lists all available disk offerings.", responseObject = DiskOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
public class ListDiskOfferingsCmd extends BaseListProjectAndAccountResourcesCmd {
public static final Logger s_logger = Logger.getLogger(ListDiskOfferingsCmd.class.getName());
@ -60,6 +61,12 @@ public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
@Parameter(name = ApiConstants.ENCRYPT, type = CommandType.BOOLEAN, description = "listed offerings support disk encryption", since = "4.18")
private Boolean encrypt;
@Parameter(name = ApiConstants.STORAGE_TYPE,
type = CommandType.STRING,
description = "the storage type of the service offering. Values are local and shared.",
since = "4.19")
private String storageType;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -84,6 +91,10 @@ public class ListDiskOfferingsCmd extends BaseListDomainResourcesCmd {
public Boolean getEncrypt() { return encrypt; }
public String getStorageType() {
return storageType;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -16,20 +16,21 @@
// under the License.
package org.apache.cloudstack.api.command.user.offering;
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListDomainResourcesCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.BaseCmd.CommandType;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
@APICommand(name = "listServiceOfferings", description = "Lists all available service offerings.", responseObject = ServiceOfferingResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListServiceOfferingsCmd extends BaseListDomainResourcesCmd {
public class ListServiceOfferingsCmd extends BaseListProjectAndAccountResourcesCmd {
public static final Logger s_logger = Logger.getLogger(ListServiceOfferingsCmd.class.getName());
@ -88,6 +89,12 @@ public class ListServiceOfferingsCmd extends BaseListDomainResourcesCmd {
since = "4.18")
private Boolean encryptRoot;
@Parameter(name = ApiConstants.STORAGE_TYPE,
type = CommandType.STRING,
description = "the storage type of the service offering. Values are local and shared.",
since = "4.19")
private String storageType;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -130,6 +137,10 @@ public class ListServiceOfferingsCmd extends BaseListDomainResourcesCmd {
public Boolean getEncryptRoot() { return encryptRoot; }
public String getStorageType() {
return storageType;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -21,18 +21,6 @@ import java.util.List;
import java.util.Map;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.command.user.UserCmd;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.SnapshotResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiCommandResourceType;
import org.apache.cloudstack.api.ApiConstants;
@ -41,13 +29,23 @@ import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.UserCmd;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
import org.apache.cloudstack.api.response.SnapshotResponse;
import org.apache.cloudstack.api.response.TemplateResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.projects.Project;
import com.cloud.storage.Snapshot;
import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate;
@ -139,6 +137,19 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "the zone for the template. Can be specified with snapshot only", since = "4.19.0")
private Long zoneId;
@Parameter(name = ApiConstants.DOMAIN_ID,
type = CommandType.UUID,
entityType = DomainResponse.class,
description = "an optional domainId. If the account parameter is used, domainId must also be used.",
since = "4.19.0")
private Long domainId;
@Parameter(name = ApiConstants.ACCOUNT,
type = CommandType.STRING,
description = "an optional accountName. Must be used with domainId.",
since = "4.19.0")
private String accountName;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@ -217,6 +228,14 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
return zoneId;
}
public Long getDomainId() {
return domainId;
}
public String getAccountName() {
return accountName;
}
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@ -232,47 +251,12 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
@Override
public long getEntityOwnerId() {
Long volumeId = getVolumeId();
Long snapshotId = getSnapshotId();
Account callingAccount = CallContext.current().getCallingAccount();
if (volumeId != null) {
Volume volume = _entityMgr.findById(Volume.class, volumeId);
if (volume != null) {
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, volume);
} else {
throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
}
} else {
Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
if (snapshot != null) {
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, snapshot);
} else {
throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
}
}
if(projectId != null){
final Project project = _projectService.getProject(projectId);
if (project != null) {
if (project.getState() == Project.State.Active) {
Account projectAccount= _accountService.getAccount(project.getProjectAccountId());
_accountService.checkAccess(callingAccount, SecurityChecker.AccessType.UseEntry, false, projectAccount);
return project.getProjectAccountId();
} else {
final PermissionDeniedException ex =
new PermissionDeniedException("Can't add resources to the project with specified projectId in state=" + project.getState() +
" as it's no longer active");
ex.addProxyObject(project.getUuid(), "projectId");
throw ex;
}
} else {
throw new InvalidParameterValueException("Unable to find project by id");
}
}
return callingAccount.getId();
ensureAccessCheck(callingAccount);
return findAccountIdToUse(callingAccount);
}
@Override
public String getEventType() {
return EventTypes.EVENT_TEMPLATE_CREATE;
@ -330,4 +314,47 @@ public class CreateTemplateCmd extends BaseAsyncCreateCmd implements UserCmd {
}
}
/***
* Performs access check on volume and snapshot for given account
* @param account
*/
private void ensureAccessCheck(Account account) {
if (volumeId != null) {
Volume volume = _entityMgr.findById(Volume.class, volumeId);
if (volume != null) {
_accountService.checkAccess(account, SecurityChecker.AccessType.UseEntry, false, volume);
} else {
throw new InvalidParameterValueException("Unable to find volume by id=" + volumeId);
}
} else {
Snapshot snapshot = _entityMgr.findById(Snapshot.class, snapshotId);
if (snapshot != null) {
_accountService.checkAccess(account, SecurityChecker.AccessType.UseEntry, false, snapshot);
} else {
throw new InvalidParameterValueException("Unable to find snapshot by id=" + snapshotId);
}
}
}
/***
* Find accountId based on accountName and domainId or projectId
* if not found, return callingAccountId for further use
* @param callingAccount
* @return accountId
*/
private Long findAccountIdToUse(Account callingAccount) {
Long accountIdToUse = null;
try {
accountIdToUse = _accountService.finalyzeAccountId(accountName, domainId, projectId, true);
} catch (InvalidParameterValueException | PermissionDeniedException ex) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("An exception occurred while finalizing account id with accountName, domainId and projectId" +
"using callingAccountId=%s", callingAccount.getUuid()), ex);
}
s_logger.warn("Unable to find accountId associated with accountName=" + accountName + " and domainId="
+ domainId + " or projectId=" + projectId + ", using callingAccountId=" + callingAccount.getUuid());
}
return accountIdToUse != null ? accountIdToUse : callingAccount.getAccountId();
}
}

View File

@ -33,6 +33,7 @@ import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.api.response.GuestOSResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.exception.ResourceAllocationException;
@ -46,7 +47,7 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
private static final String s_name = "postuploadtemplateresponse";
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, required = true, description = "the display text of the template. This is usually used for display purposes.", length = 4096)
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "the display text of the template. This is usually used for display purposes.", length = 4096)
private String displayText;
@Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "the target hypervisor for the template")
@ -95,7 +96,7 @@ public class GetUploadParamsForTemplateCmd extends AbstractGetUploadParamsCmd {
private Boolean deployAsIs;
public String getDisplayText() {
return displayText;
return StringUtils.isBlank(displayText) ? getName() : displayText;
}
public String getHypervisor() {

View File

@ -125,6 +125,9 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd {
vpnResponse.setId(vpnUser.getUuid());
vpnResponse.setUserName(vpnUser.getUsername());
vpnResponse.setAccountName(account.getAccountName());
// re-retrieve the vpnuser, as the call to `applyVpnUsers` might have changed the state
vpnUser = _entityMgr.findById(VpnUser.class, getEntityId());
vpnResponse.setState(vpnUser.getState().toString());
Domain domain = _entityMgr.findById(Domain.class, account.getDomainId());
if (domain != null) {

View File

@ -124,7 +124,7 @@ public class AcquireIPAddressResponse extends BaseResponse implements Controlle
private String networkId;
@SerializedName(ApiConstants.STATE)
@Param(description = "State of the ip address. Can be: Allocatin, Allocated and Releasing")
@Param(description = "State of the ip address. Can be: Allocating, Allocated and Releasing")
private String state;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID)

View File

@ -0,0 +1,293 @@
// 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.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.storage.object.Bucket;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
@EntityReference(value = Bucket.class)
@SuppressWarnings("unused")
public class BucketResponse extends BaseResponseWithTagInformation implements ControlledViewEntityResponse, ControlledEntityResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "ID of the Bucket")
private String id;
@SerializedName(ApiConstants.NAME)
@Param(description = "name of the Bucket")
private String name;
@SerializedName(ApiConstants.CREATED)
@Param(description = "the date the Bucket was created")
private Date created;
@SerializedName(ApiConstants.ACCOUNT)
@Param(description = "the account associated with the Bucket")
private String accountName;
@SerializedName(ApiConstants.PROJECT_ID)
@Param(description = "the project id of the bucket")
private String projectId;
@SerializedName(ApiConstants.PROJECT)
@Param(description = "the project name of the bucket")
private String projectName;
@SerializedName(ApiConstants.DOMAIN_ID)
@Param(description = "the ID of the domain associated with the bucket")
private String domainId;
@SerializedName(ApiConstants.DOMAIN)
@Param(description = "the domain associated with the bucket")
private String domainName;
@SerializedName(ApiConstants.OBJECT_STORAGE_ID)
@Param(description = "id of the object storage hosting the Bucket; returned to admin user only")
private String objectStoragePoolId;
@SerializedName(ApiConstants.OBJECT_STORAGE)
@Param(description = "Name of the object storage hosting the Bucket; returned to admin user only")
private String objectStoragePool;
@SerializedName(ApiConstants.SIZE)
@Param(description = "Total size of objects in Bucket")
private Long size;
@SerializedName(ApiConstants.STATE)
@Param(description = "State of the Bucket")
private String state;
@SerializedName(ApiConstants.QUOTA)
@Param(description = "Bucket Quota in GB")
private Integer quota;
@SerializedName(ApiConstants.ENCRYPTION)
@Param(description = "Bucket Encryption")
private Boolean encryption;
@SerializedName(ApiConstants.VERSIONING)
@Param(description = "Bucket Versioning")
private Boolean versioning;
@SerializedName(ApiConstants.OBJECT_LOCKING)
@Param(description = "Bucket Object Locking")
private Boolean objectLock;
@SerializedName(ApiConstants.POLICY)
@Param(description = "Bucket Access Policy")
private String policy;
@SerializedName(ApiConstants.URL)
@Param(description = "Bucket URL")
private String bucketURL;
@SerializedName(ApiConstants.ACCESS_KEY)
@Param(description = "Bucket Access Key")
private String accessKey;
@SerializedName(ApiConstants.SECRET_KEY)
@Param(description = "Bucket Secret Key")
private String secretKey;
@SerializedName(ApiConstants.PROVIDER)
@Param(description = "Object storage provider")
private String provider;
public BucketResponse() {
tags = new LinkedHashSet<ResourceTagResponse>();
}
@Override
public String getObjectId() {
return this.getId();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setCreated(Date created) {
this.created = created;
}
@Override
public void setAccountName(String accountName) {
this.accountName = accountName;
}
@Override
public void setDomainId(String domainId) {
this.domainId = domainId;
}
@Override
public void setDomainName(String domainName) {
this.domainName = domainName;
}
@Override
public void setProjectId(String projectId) {
this.projectId = projectId;
}
@Override
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public void setTags(Set<ResourceTagResponse> tags) {
this.tags = tags;
}
public void setObjectStoragePoolId(String objectStoragePoolId) {
this.objectStoragePoolId = objectStoragePoolId;
}
public String getName() {
return name;
}
public Date getCreated() {
return created;
}
public String getAccountName() {
return accountName;
}
public String getProjectId() {
return projectId;
}
public String getProjectName() {
return projectName;
}
public String getDomainId() {
return domainId;
}
public String getDomainName() {
return domainName;
}
public String getObjectStoragePoolId() {
return objectStoragePoolId;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public long getQuota() {
return quota;
}
public void setQuota(Integer quota) {
this.quota = quota;
}
public boolean isVersioning() {
return versioning;
}
public void setVersioning(boolean versioning) {
this.versioning = versioning;
}
public boolean isEncryption() {
return encryption;
}
public void setEncryption(boolean encryption) {
this.encryption = encryption;
}
public boolean isObjectLock() {
return objectLock;
}
public void setObjectLock(boolean objectLock) {
this.objectLock = objectLock;
}
public String getPolicy() {
return policy;
}
public void setPolicy(String policy) {
this.policy = policy;
}
public String getBucketURL() {
return bucketURL;
}
public void setBucketURL(String bucketURL) {
this.bucketURL = bucketURL;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public void setState(Bucket.State state) {
this.state = state.toString();
}
public String getState() {
return state;
}
public void setObjectStoragePool(String objectStoragePool) {
this.objectStoragePool = objectStoragePool;
}
public String getObjectStoragePool() {
return objectStoragePool;
}
public String getProvider() {
return provider;
}
public void setProvider(String provider) {
this.provider = provider;
}
}

View File

@ -221,6 +221,10 @@ public class HostResponse extends BaseResponseWithAnnotations {
@Param(description = "comma-separated list of tags for the host")
private String hostTags;
@SerializedName(ApiConstants.IS_TAG_A_RULE)
@Param(description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
@SerializedName("hasenoughcapacity")
@Param(description = "true if this host has enough CPU and RAM capacity to migrate a VM to it, false otherwise")
private Boolean hasEnoughCapacity;
@ -732,4 +736,12 @@ public class HostResponse extends BaseResponseWithAnnotations {
public void setEncryptionSupported(Boolean encryptionSupported) {
this.encryptionSupported = encryptionSupported;
}
public Boolean getIsTagARule() {
return isTagARule;
}
public void setIsTagARule(Boolean tagARule) {
isTagARule = tagARule;
}
}

View File

@ -128,7 +128,7 @@ public class IPAddressResponse extends BaseResponseWithAnnotations implements Co
private String networkId;
@SerializedName(ApiConstants.STATE)
@Param(description = "State of the ip address. Can be: Allocatin, Allocated and Releasing")
@Param(description = "State of the ip address. Can be: Allocating, Allocated, Releasing, Reserved and Free")
private String state;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID)

View File

@ -0,0 +1,130 @@
//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.response;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import java.util.Date;
@EntityReference(value = {PublicIpQuarantine.class})
public class IpQuarantineResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "ID of the quarantine process.")
private String id;
@SerializedName(ApiConstants.IP_ADDRESS)
@Param(description = "The public IP address in quarantine.")
private String publicIpAddress;
@SerializedName(ApiConstants.PREVIOUS_OWNER_ID)
@Param(description = "Account ID of the previous public IP address owner.")
private String previousOwnerId;
@SerializedName(ApiConstants.PREVIOUS_OWNER_NAME)
@Param(description = "Account name of the previous public IP address owner.")
private String previousOwnerName;
@SerializedName(ApiConstants.CREATED)
@Param(description = "When the quarantine was created.")
private Date created;
@SerializedName(ApiConstants.REMOVED)
@Param(description = "When the quarantine was removed.")
private Date removed;
@SerializedName(ApiConstants.END_DATE)
@Param(description = "End date for the quarantine.")
private Date endDate;
@SerializedName(ApiConstants.REMOVAL_REASON)
@Param(description = "The reason for removing the IP from quarantine prematurely.")
private String removalReason;
public IpQuarantineResponse() {
super("quarantinedips");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPublicIpAddress() {
return publicIpAddress;
}
public void setPublicIpAddress(String publicIpAddress) {
this.publicIpAddress = publicIpAddress;
}
public String getPreviousOwnerId() {
return previousOwnerId;
}
public void setPreviousOwnerId(String previousOwnerId) {
this.previousOwnerId = previousOwnerId;
}
public String getPreviousOwnerName() {
return previousOwnerName;
}
public void setPreviousOwnerName(String previousOwnerName) {
this.previousOwnerName = previousOwnerName;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getRemoved() {
return removed;
}
public void setRemoved(Date removed) {
this.removed = removed;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getRemovalReason() {
return removalReason;
}
public void setRemovalReason(String removalReason) {
this.removalReason = removalReason;
}
}

View File

@ -0,0 +1,106 @@
// 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.response;
import com.cloud.serializer.Param;
import org.apache.cloudstack.storage.object.ObjectStore;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.BaseResponseWithAnnotations;
import org.apache.cloudstack.api.EntityReference;
@EntityReference(value = ObjectStore.class)
public class ObjectStoreResponse extends BaseResponseWithAnnotations {
@SerializedName("id")
@Param(description = "the ID of the object store")
private String id;
@SerializedName("name")
@Param(description = "the name of the object store")
private String name;
@SerializedName("url")
@Param(description = "the url of the object store")
private String url;
@SerializedName("providername")
@Param(description = "the provider name of the object store")
private String providerName;
@SerializedName("storagetotal")
@Param(description = "the total size of the object store")
private Long storageTotal;
@SerializedName("storageused")
@Param(description = "the object store currently used size")
private Long storageUsed;
public ObjectStoreResponse() {
}
@Override
public String getObjectId() {
return this.getId();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public Long getStorageTotal() {
return storageTotal;
}
public void setStorageTotal(Long storageTotal) {
this.storageTotal = storageTotal;
}
public Long getStorageUsed() {
return storageUsed;
}
public void setStorageUsed(Long storageUsed) {
this.storageUsed = storageUsed;
}
}

View File

@ -68,7 +68,7 @@ public class PortableIpResponse extends BaseResponse {
private Date allocated;
@SerializedName(ApiConstants.STATE)
@Param(description = "State of the ip address. Can be: Allocatin, Allocated and Releasing")
@Param(description = "State of the ip address. Can be: Allocating, Allocated, Releasing and Free")
private String state;
public void setRegionId(Integer regionId) {

View File

@ -0,0 +1,141 @@
//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.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.secstorage.heuristics.Heuristic;
import java.util.Date;
import static org.apache.cloudstack.api.ApiConstants.HEURISTIC_TYPE_VALID_OPTIONS;
@EntityReference(value = {Heuristic.class})
public class SecondaryStorageHeuristicsResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "ID of the heuristic.")
private String id;
@SerializedName(ApiConstants.NAME)
@Param(description = "Name of the heuristic.")
private String name;
@SerializedName(ApiConstants.DESCRIPTION)
@Param(description = "Description of the heuristic.")
private String description;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "The zone which the heuristic is valid upon.")
private String zoneId;
@SerializedName(ApiConstants.TYPE)
@Param(description = "The resource type directed to a specific secondary storage by the selector. " + HEURISTIC_TYPE_VALID_OPTIONS)
private String type;
@SerializedName(ApiConstants.HEURISTIC_RULE)
@Param(description = "The heuristic rule, in JavaScript language, used to select a secondary storage to be directed.")
private String heuristicRule;
@SerializedName(ApiConstants.CREATED)
@Param(description = "When the heuristic was created.")
private Date created;
@SerializedName(ApiConstants.REMOVED)
@Param(description = "When the heuristic was removed.")
private Date removed;
public SecondaryStorageHeuristicsResponse(String id, String name, String description, String zoneId, String type, String heuristicRule, Date created, Date removed) {
super("heuristics");
this.id = id;
this.name = name;
this.description = description;
this.zoneId = zoneId;
this.type = type;
this.heuristicRule = heuristicRule;
this.created = created;
this.removed = removed;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getZoneId() {
return zoneId;
}
public void setZoneId(String zoneId) {
this.zoneId = zoneId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getHeuristicRule() {
return heuristicRule;
}
public void setHeuristicRule(String heuristicRule) {
this.heuristicRule = heuristicRule;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getRemoved() {
return removed;
}
public void setRemoved(Date removed) {
this.removed = removed;
}
}

View File

@ -101,6 +101,10 @@ public class StoragePoolResponse extends BaseResponseWithAnnotations {
@Param(description = "the tags for the storage pool")
private String tags;
@SerializedName(ApiConstants.IS_TAG_A_RULE)
@Param(description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
private Boolean isTagARule;
@SerializedName(ApiConstants.STATE)
@Param(description = "the state of the storage pool")
private StoragePoolStatus state;
@ -304,6 +308,14 @@ public class StoragePoolResponse extends BaseResponseWithAnnotations {
this.tags = tags;
}
public Boolean getIsTagARule() {
return isTagARule;
}
public void setIsTagARule(Boolean tagARule) {
isTagARule = tagARule;
}
public StoragePoolStatus getState() {
return state;
}

View File

@ -57,7 +57,7 @@ public class VpnUsersResponse extends BaseResponse implements ControlledEntityRe
private String projectName;
@SerializedName(ApiConstants.STATE)
@Param(description = "the state of the Vpn User")
@Param(description = "the state of the Vpn User, can be 'Add', 'Revoke' or 'Active'.")
private String state;
public void setId(String id) {

View File

@ -28,13 +28,17 @@ import org.apache.cloudstack.api.command.admin.resource.icon.ListResourceIconCmd
import org.apache.cloudstack.api.command.admin.router.GetRouterHealthCheckResultsCmd;
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListObjectStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListSecondaryStagingStoresCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
import org.apache.cloudstack.api.command.admin.storage.heuristics.ListSecondaryStorageSelectorsCmd;
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
import org.apache.cloudstack.api.command.user.address.ListQuarantinedIpsCmd;
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
import org.apache.cloudstack.api.command.user.bucket.ListBucketsCmd;
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
@ -55,6 +59,7 @@ import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.BucketResponse;
import org.apache.cloudstack.api.response.DetailOptionsResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainResponse;
@ -64,8 +69,10 @@ import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.HostTagResponse;
import org.apache.cloudstack.api.response.ImageStoreResponse;
import org.apache.cloudstack.api.response.InstanceGroupResponse;
import org.apache.cloudstack.api.response.IpQuarantineResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.ManagementServerResponse;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.cloudstack.api.response.ProjectAccountResponse;
import org.apache.cloudstack.api.response.ProjectInvitationResponse;
import org.apache.cloudstack.api.response.ProjectResponse;
@ -73,6 +80,7 @@ import org.apache.cloudstack.api.response.ResourceDetailResponse;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
import org.apache.cloudstack.api.response.SecondaryStorageHeuristicsResponse;
import org.apache.cloudstack.api.response.SecurityGroupResponse;
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
import org.apache.cloudstack.api.response.SnapshotResponse;
@ -183,7 +191,15 @@ public interface QueryService {
List<RouterHealthCheckResultResponse> listRouterHealthChecks(GetRouterHealthCheckResultsCmd cmd);
ListResponse<SecondaryStorageHeuristicsResponse> listSecondaryStorageSelectors(ListSecondaryStorageSelectorsCmd cmd);
ListResponse<IpQuarantineResponse> listQuarantinedIps(ListQuarantinedIpsCmd cmd);
ListResponse<SnapshotResponse> listSnapshots(ListSnapshotsCmd cmd);
SnapshotResponse listSnapshot(CopySnapshotCmd cmd);
ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd listObjectStoragePoolsCmd);
ListResponse<BucketResponse> searchForBuckets(ListBucketsCmd listBucketsCmd);
}

View File

@ -0,0 +1,40 @@
// 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.secstorage.heuristics;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
public interface Heuristic extends InternalIdentity, Identity {
String getName();
String getDescription();
Long getZoneId();
String getType();
String getHeuristicRule();
Date getCreated();
Date getRemoved();
}

View File

@ -0,0 +1,25 @@
// 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.secstorage.heuristics;
/**
* The type of the heuristic used in the allocation process of secondary storage resources.
* Valid options are: {@link #ISO}, {@link #SNAPSHOT}, {@link #TEMPLATE} and {@link #VOLUME}
*/
public enum HeuristicType {
ISO, SNAPSHOT, TEMPLATE, VOLUME
}

View File

@ -0,0 +1,64 @@
// 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.storage.object;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
public interface Bucket extends ControlledEntity, Identity, InternalIdentity {
long getObjectStoreId();
Date getCreated();
State getState();
void setName(String name);
Long getSize();
Integer getQuota();
boolean isVersioning();
boolean isEncryption();
boolean isObjectLock();
String getPolicy();
String getBucketURL();
String getAccessKey();
String getSecretKey();
public enum State {
Allocated, Created, Destroyed;
@Override
public String toString() {
return this.name();
}
public boolean equals(String status) {
return this.toString().equalsIgnoreCase(status);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* 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.storage.object;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.user.Account;
import org.apache.cloudstack.api.command.user.bucket.CreateBucketCmd;
import org.apache.cloudstack.api.command.user.bucket.UpdateBucketCmd;
public interface BucketApiService {
/**
* Creates the database object for a Bucket based on the given criteria
*
* @param cmd
* the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
* name)
* @return the Bucket object
*/
Bucket allocBucket(CreateBucketCmd cmd) throws ResourceAllocationException;
/**
* Creates the Bucket based on the given criteria
*
* @param cmd
* the API command wrapping the criteria (account/domainId [admin only], zone, diskOffering, snapshot,
* name)
* @return the Bucket object
*/
Bucket createBucket(CreateBucketCmd cmd);
boolean deleteBucket(long bucketId, Account caller);
boolean updateBucket(UpdateBucketCmd cmd, Account caller);
void getBucketUsage();
}

View File

@ -0,0 +1,40 @@
// 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.storage.object;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface ObjectStore extends Identity, InternalIdentity {
/**
* @return name of the object store.
*/
String getName();
/**
* @return object store provider name
*/
String getProviderName();
/**
*
* @return uri
*/
String getUrl();
}

View File

@ -45,6 +45,7 @@ public class UsageTypes {
public static final int VOLUME_SECONDARY = 26;
public static final int VM_SNAPSHOT_ON_PRIMARY = 27;
public static final int BACKUP = 28;
public static final int BUCKET = 29;
public static List<UsageTypeResponse> listUsageTypes() {
List<UsageTypeResponse> responseList = new ArrayList<UsageTypeResponse>();
@ -70,6 +71,7 @@ public class UsageTypes {
responseList.add(new UsageTypeResponse(VOLUME_SECONDARY, "Volume on secondary storage usage"));
responseList.add(new UsageTypeResponse(VM_SNAPSHOT_ON_PRIMARY, "VM Snapshot on primary storage usage"));
responseList.add(new UsageTypeResponse(BACKUP, "Backup storage usage"));
responseList.add(new UsageTypeResponse(BUCKET, "Bucket storage usage"));
return responseList;
}
}

View File

@ -0,0 +1,97 @@
/*
* 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.storage;
import com.cloud.exception.DiscoveryException;
import com.cloud.storage.StorageService;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.HashMap;
import java.util.Map;
import static org.mockito.ArgumentMatchers.anyObject;
@RunWith(MockitoJUnitRunner.class)
public class AddObjectStoragePoolCmdTest {
public static final Logger s_logger = Logger.getLogger(AddObjectStoragePoolCmdTest.class.getName());
@Mock
StorageService storageService;
@Mock
ObjectStore objectStore;
@Mock
ResponseGenerator responseGenerator;
@Spy
AddObjectStoragePoolCmd addObjectStoragePoolCmdSpy;
String name = "testObjStore";
String url = "testURL";
String provider = "Simulator";
Map<String, String> details;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
details = new HashMap<>();
addObjectStoragePoolCmdSpy = Mockito.spy(new AddObjectStoragePoolCmd());
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "name", name);
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "url", url);
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "providerName", provider);
ReflectionTestUtils.setField(addObjectStoragePoolCmdSpy, "details", details);
addObjectStoragePoolCmdSpy._storageService = storageService;
addObjectStoragePoolCmdSpy._responseGenerator = responseGenerator;
}
@After
public void tearDown() throws Exception {
CallContext.unregister();
}
@Test
public void testAddObjectStore() throws DiscoveryException {
Mockito.doReturn(objectStore).when(storageService).discoverObjectStore(Mockito.anyString(),
Mockito.anyString(), Mockito.anyString(), anyObject());
ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
Mockito.doReturn(objectStoreResponse).when(responseGenerator).createObjectStoreResponse(anyObject());
addObjectStoragePoolCmdSpy.execute();
Mockito.verify(storageService, Mockito.times(1))
.discoverObjectStore(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.storage;
import com.cloud.storage.StorageService;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
public class DeleteObjectStoragePoolCmdTest {
public static final Logger s_logger = Logger.getLogger(DeleteObjectStoragePoolCmdTest.class.getName());
@Mock
private StorageService storageService;
@Spy
DeleteObjectStoragePoolCmd deleteObjectStoragePoolCmd;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
deleteObjectStoragePoolCmd = Mockito.spy(new DeleteObjectStoragePoolCmd());
deleteObjectStoragePoolCmd._storageService = storageService;
}
@After
public void tearDown() throws Exception {
CallContext.unregister();
}
@Test
public void testDeleteObjectStore() {
Mockito.doReturn(true).when(storageService).deleteObjectStore(deleteObjectStoragePoolCmd);
deleteObjectStoragePoolCmd.execute();
Mockito.verify(storageService, Mockito.times(1))
.deleteObjectStore(deleteObjectStoragePoolCmd);
}
}

View File

@ -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
* 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.storage;
import com.cloud.storage.StorageService;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.response.ObjectStoreResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.storage.object.ObjectStore;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.springframework.test.util.ReflectionTestUtils;
import static org.mockito.ArgumentMatchers.anyObject;
public class UpdateObjectStoragePoolCmdTest {
public static final Logger s_logger = Logger.getLogger(UpdateObjectStoragePoolCmdTest.class.getName());
@Mock
private StorageService storageService;
@Spy
UpdateObjectStoragePoolCmd updateObjectStoragePoolCmd;
@Mock
ObjectStore objectStore;
@Mock
ResponseGenerator responseGenerator;
private String name = "testObjStore";
private String url = "testURL";
private String provider = "Simulator";
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
updateObjectStoragePoolCmd = Mockito.spy(new UpdateObjectStoragePoolCmd());
updateObjectStoragePoolCmd._storageService = storageService;
updateObjectStoragePoolCmd._responseGenerator = responseGenerator;
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "name", name);
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "url", url);
ReflectionTestUtils.setField(updateObjectStoragePoolCmd, "id", 1L);
}
@After
public void tearDown() throws Exception {
CallContext.unregister();
}
@Test
public void testUpdateObjectStore() {
Mockito.doReturn(objectStore).when(storageService).updateObjectStore(1L, updateObjectStoragePoolCmd);
ObjectStoreResponse objectStoreResponse = new ObjectStoreResponse();
Mockito.doReturn(objectStoreResponse).when(responseGenerator).createObjectStoreResponse(anyObject());
updateObjectStoragePoolCmd.execute();
Mockito.verify(storageService, Mockito.times(1))
.updateObjectStore(1L, updateObjectStoragePoolCmd);
}
}

View File

@ -29,4 +29,20 @@ public class CreateTemplateCmdTest {
ReflectionTestUtils.setField(cmd, "zoneId", id);
Assert.assertEquals(id, cmd.getZoneId());
}
@Test
public void testDomainId() {
final CreateTemplateCmd cmd = new CreateTemplateCmd();
Long id = 2L;
ReflectionTestUtils.setField(cmd, "domainId", id);
Assert.assertEquals(id, cmd.getDomainId());
}
@Test
public void testGetAccountName() {
final CreateTemplateCmd cmd = new CreateTemplateCmd();
String accountName = "user1";
ReflectionTestUtils.setField(cmd, "accountName", accountName);
Assert.assertEquals(accountName, cmd.getAccountName());
}
}

View File

@ -582,6 +582,21 @@
<artifactId>cloud-plugin-shutdown</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-object</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-storage-object-minio</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-storage-object-simulator</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -0,0 +1,30 @@
/*
* 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.engine.subsystem.api.storage;
import org.apache.cloudstack.storage.object.Bucket;
public interface BucketInfo extends DataObject, Bucket {
void addPayload(Object data);
Object getPayload();
Bucket getBucket();
}

View File

@ -35,6 +35,8 @@ public interface DataStoreManager {
List<DataStore> getImageStoresByScopeExcludingReadOnly(ZoneScope scope);
List<DataStore> getImageStoresByZoneIds(Long ... zoneIds);
DataStore getRandomImageStore(long zoneId);
DataStore getRandomUsableImageStore(long zoneId);
@ -55,5 +57,7 @@ public interface DataStoreManager {
boolean isRegionStore(DataStore store);
DataStore getImageStoreByUuid(String uuid);
Long getStoreZoneId(long storeId, DataStoreRole role);
}

View File

@ -31,7 +31,7 @@ public interface DataStoreProvider {
String DEFAULT_PRIMARY = "DefaultPrimary";
enum DataStoreProviderType {
PRIMARY, IMAGE, ImageCache
PRIMARY, IMAGE, ImageCache, OBJECT
}
DataStoreLifeCycle getDataStoreLifeCycle();

View File

@ -33,4 +33,6 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS
DataStoreProvider getDefaultCacheDataStoreProvider();
List<DataStoreProvider> getProviders();
DataStoreProvider getDefaultObjectStoreProvider();
}

View File

@ -0,0 +1,22 @@
// 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.engine.subsystem.api.storage;
public interface ObjectStorageService {
}

View File

@ -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.engine.subsystem.api.storage;
public interface ObjectStoreProvider extends DataStoreProvider {
}

View File

@ -43,6 +43,8 @@ public class PrimaryDataStoreParameters {
private boolean managed;
private Long capacityIops;
private Boolean isTagARule;
/**
* @return the userInfo
*/
@ -277,4 +279,12 @@ public class PrimaryDataStoreParameters {
public void setUsedBytes(long usedBytes) {
this.usedBytes = usedBytes;
}
public Boolean isTagARule() {
return isTagARule;
}
public void setIsTagARule(Boolean isTagARule) {
this.isTagARule = isTagARule;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.storage.object;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import java.util.List;
import java.util.Map;
public interface ObjectStoreEntity extends DataStore, ObjectStore {
Bucket createBucket(Bucket bucket, boolean objectLock);
List<Bucket> listBuckets();
boolean createUser(long accountId);
boolean deleteBucket(String name);
boolean setBucketEncryption(String name);
boolean deleteBucketEncryption(String name);
boolean setBucketVersioning(String name);
boolean deleteBucketVersioning(String name);
void setBucketPolicy(String name, String policy);
void setQuota(String name, int quota);
Map<String, Long> getAllBucketsUsage();
}

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.network;
import java.util.Date;
import java.util.List;
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
@ -238,5 +239,52 @@ public interface IpAddressManager {
public static final String MESSAGE_ASSIGN_IPADDR_EVENT = "Message.AssignIpAddr.Event";
public static final String MESSAGE_RELEASE_IPADDR_EVENT = "Message.ReleaseIpAddr.Event";
/**
* Checks if the given public IP address is not in active quarantine.
* It returns `true` if:
* <ul>
* <li>The IP was never in quarantine;</li>
* <li>The IP was in quarantine, but the quarantine expired;</li>
* <li>The IP is still in quarantine; however, the new owner is the same as the previous owner, therefore, the IP can be allocated.</li>
* </ul>
*
* It returns `false` if:
* <ul>
* <li>The IP is in active quarantine and the new owner is different from the previous owner.</li>
* </ul>
*
* @param ip used to check if it is in active quarantine.
* @param account used to identify the new owner of the public IP.
* @return true if the IP can be allocated, and false otherwise.
*/
boolean canPublicIpAddressBeAllocated(IpAddress ip, Account account);
/**
* Adds the given public IP address to quarantine for the duration of the global configuration `public.ip.address.quarantine.duration` value.
*
* @param publicIpAddress to be quarantined.
* @param domainId used to retrieve the quarantine duration.
* @return the {@link PublicIpQuarantine} persisted in the database.
*/
PublicIpQuarantine addPublicIpAddressToQuarantine(IpAddress publicIpAddress, Long domainId);
/**
* Prematurely removes a public IP address from quarantine. It is required to provide a reason for removing it.
*
* @param quarantineProcessId the ID of the active quarantine process.
* @param removalReason for prematurely removing the public IP address from quarantine.
*/
void removePublicIpAddressFromQuarantine(Long quarantineProcessId, String removalReason);
/**
* Updates the end date of a public IP address in active quarantine. It can increase and decrease the duration of the quarantine.
*
* @param quarantineProcessId the ID of the quarantine process.
* @param endDate the new end date for the quarantine.
* @return the updated quarantine object.
*/
PublicIpQuarantine updatePublicIpAddressInQuarantine(Long quarantineProcessId, Date endDate);
void updateSourceNatIpAddress(IPAddressVO requestedIp, List<IPAddressVO> userIps) throws Exception;
}

View File

@ -192,6 +192,9 @@ public interface StorageManager extends StorageService {
ConfigKey.Scope.Global,
null);
ConfigKey<Long> HEURISTICS_SCRIPT_TIMEOUT = new ConfigKey<>("Advanced", Long.class, "heuristics.script.timeout", "3000",
"The maximum runtime, in milliseconds, to execute the heuristic rule; if it is reached, a timeout will happen.", true);
/**
* should we execute in sequence not involving any storages?
* @return tru if commands should execute in sequence

View File

@ -34,6 +34,7 @@ import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StoragePool;
import com.cloud.storage.VMTemplateStoragePoolVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.utils.Pair;
import com.cloud.vm.VirtualMachineProfile;
@ -116,7 +117,7 @@ public interface TemplateManager {
Long getTemplateSize(long templateId, long zoneId);
DataStore getImageStore(String storeUuid, Long zoneId);
DataStore getImageStore(String storeUuid, Long zoneId, VolumeVO volume);
String getChecksum(DataStore store, String templatePath, String algorithm);

View File

@ -55,6 +55,7 @@
<module>storage/configdrive</module>
<module>storage/datamotion</module>
<module>storage/image</module>
<module>storage/object</module>
<module>storage/snapshot</module>
<module>storage/volume</module>
<module>userdata/cloud-init</module>

View File

@ -24,6 +24,7 @@ import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.commons.lang3.BooleanUtils;
@Entity
@Table(name = "host_tags")
@ -39,12 +40,22 @@ public class HostTagVO implements InternalIdentity {
@Column(name = "tag")
private String tag;
@Column(name = "is_tag_a_rule")
private boolean isTagARule;
protected HostTagVO() {
}
public HostTagVO(long hostId, String tag) {
this.hostId = hostId;
this.tag = tag;
this.isTagARule = false;
}
public HostTagVO(long hostId, String tag, Boolean isTagARule) {
this.hostId = hostId;
this.tag = tag;
this.isTagARule = BooleanUtils.toBooleanDefaultIfNull(isTagARule, false);
}
public long getHostId() {
@ -59,6 +70,11 @@ public class HostTagVO implements InternalIdentity {
this.tag = tag;
}
public boolean getIsTagARule() {
return isTagARule;
}
@Override
public long getId() {
return id;

View File

@ -39,6 +39,7 @@ import javax.persistence.TemporalType;
import javax.persistence.Transient;
import com.cloud.agent.api.VgpuTypesInfo;
import com.cloud.host.dao.HostTagsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.offering.ServiceOffering;
import com.cloud.resource.ResourceState;
@ -46,7 +47,10 @@ import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
import java.util.Arrays;
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@Entity
@ -159,6 +163,14 @@ public class HostVO implements Host {
@Transient
List<String> hostTags;
/**
* This is a delayed load value.
* If the value is null, then this field has not been loaded yet.
* Call host dao to load it.
*/
@Transient
Boolean isTagARule;
// This value is only for saving and current cannot be loaded.
@Transient
HashMap<String, HashMap<String, VgpuTypesInfo>> groupDetails = new HashMap<String, HashMap<String, VgpuTypesInfo>>();
@ -322,8 +334,13 @@ public class HostVO implements Host {
return hostTags;
}
public void setHostTags(List<String> hostTags) {
public void setHostTags(List<String> hostTags, Boolean isTagARule) {
this.hostTags = hostTags;
this.isTagARule = isTagARule;
}
public Boolean getIsTagARule() {
return isTagARule;
}
public HashMap<String, HashMap<String, VgpuTypesInfo>> getGpuGroupDetails() {
@ -748,6 +765,11 @@ public class HostVO implements Host {
if (serviceOffering == null) {
return false;
}
if (BooleanUtils.isTrue(this.getIsTagARule())) {
return TagAsRuleHelper.interpretTagAsRule(this.getHostTags().get(0), serviceOffering.getHostTag(), HostTagsDao.hostTagRuleExecutionTimeout.value());
}
if (StringUtils.isEmpty(serviceOffering.getHostTag())) {
return true;
}

View File

@ -108,6 +108,8 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
List<HostVO> listAllHostsByZoneAndHypervisorType(long zoneId, HypervisorType hypervisorType);
List<HostVO> listAllHostsThatHaveNoRuleTag(Host.Type type, Long clusterId, Long podId, Long dcId);
List<HostVO> listAllHostsByType(Host.Type type);
HostVO findByPublicIp(String publicIp);
@ -161,4 +163,8 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
* @return ordered list of hypervisor versions
*/
List<String> listOrderedHostsHypervisorVersionsInDatacenter(long datacenterId, HypervisorType hypervisorType);
List<HostVO> findHostsWithTagRuleThatMatchComputeOferringTags(String computeOfferingTags);
List<Long> findClustersThatMatchHostTagRule(String computeOfferingTags);
}

View File

@ -22,9 +22,11 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TimeZone;
import java.util.stream.Collectors;
@ -32,6 +34,8 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.TableGenerator;
import org.apache.cloudstack.utils.jsinterpreter.TagAsRuleHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import com.cloud.agent.api.VgpuTypesInfo;
@ -80,8 +84,8 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
private static final Logger state_logger = Logger.getLogger(ResourceState.class);
private static final String LIST_HOST_IDS_BY_COMPUTETAGS = "SELECT filtered.host_id, COUNT(filtered.tag) AS tag_count "
+ "FROM (SELECT host_id, tag FROM host_tags GROUP BY host_id,tag) AS filtered "
+ "WHERE tag IN(%s) "
+ "FROM (SELECT host_id, tag, is_tag_a_rule FROM host_tags GROUP BY host_id,tag) AS filtered "
+ "WHERE tag IN(%s) AND is_tag_a_rule = 0 "
+ "GROUP BY host_id "
+ "HAVING tag_count = %s ";
private static final String SEPARATOR = ",";
@ -148,6 +152,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected GenericSearchBuilder<ClusterVO, Long> AllClustersSearch;
protected SearchBuilder<HostVO> HostsInClusterSearch;
protected SearchBuilder<HostVO> searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag;
protected SearchBuilder<HostTagVO> searchBuilderFindByRuleTag;
protected Attribute _statusAttr;
protected Attribute _resourceStateAttr;
protected Attribute _msIdAttr;
@ -455,6 +463,22 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
HostIdSearch.and("dataCenterId", HostIdSearch.entity().getDataCenterId(), Op.EQ);
HostIdSearch.done();
searchBuilderFindByRuleTag = _hostTagsDao.createSearchBuilder();
searchBuilderFindByRuleTag.and("is_tag_a_rule", searchBuilderFindByRuleTag.entity().getIsTagARule(), Op.EQ);
searchBuilderFindByRuleTag.or("tagDoesNotExist", searchBuilderFindByRuleTag.entity().getIsTagARule(), Op.NULL);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag = createSearchBuilder();
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.and("id", searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getId(), Op.EQ);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.and("type", searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getType(), Op.EQ);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.and("cluster_id", searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getClusterId(), Op.EQ);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.and("pod_id", searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getPodId(), Op.EQ);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.and("data_center_id", searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getDataCenterId(), Op.EQ);
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.join("id", searchBuilderFindByRuleTag, searchBuilderFindByRuleTag.entity().getHostId(),
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.entity().getId(), JoinType.LEFTOUTER);
searchBuilderFindByRuleTag.done();
searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.done();
_statusAttr = _allAttributes.get("status");
_msIdAttr = _allAttributes.get("managementServerId");
_pingTimeAttr = _allAttributes.get("lastPinged");
@ -792,9 +816,12 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
@Override
public List<HostVO> listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId, String haTag) {
SearchBuilder<HostTagVO> hostTagSearch = null;
SearchBuilder<HostTagVO> hostTagSearch = _hostTagsDao.createSearchBuilder();
hostTagSearch.and();
hostTagSearch.op("isTagARule", hostTagSearch.entity().getIsTagARule(), Op.EQ);
hostTagSearch.or("tagDoesNotExist", hostTagSearch.entity().getIsTagARule(), Op.NULL);
hostTagSearch.cp();
if (haTag != null && !haTag.isEmpty()) {
hostTagSearch = _hostTagsDao.createSearchBuilder();
hostTagSearch.and().op("tag", hostTagSearch.entity().getTag(), SearchCriteria.Op.NEQ);
hostTagSearch.or("tagNull", hostTagSearch.entity().getTag(), SearchCriteria.Op.NULL);
hostTagSearch.cp();
@ -809,12 +836,14 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
hostSearch.and("status", hostSearch.entity().getStatus(), SearchCriteria.Op.EQ);
hostSearch.and("resourceState", hostSearch.entity().getResourceState(), SearchCriteria.Op.EQ);
if (haTag != null && !haTag.isEmpty()) {
hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
}
hostSearch.join("hostTagSearch", hostTagSearch, hostSearch.entity().getId(), hostTagSearch.entity().getHostId(), JoinBuilder.JoinType.LEFTOUTER);
SearchCriteria<HostVO> sc = hostSearch.create();
sc.setJoinParameters("hostTagSearch", "isTagARule", false);
if (haTag != null && !haTag.isEmpty()) {
sc.setJoinParameters("hostTagSearch", "tag", haTag);
}
@ -846,8 +875,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
@Override
public void loadHostTags(HostVO host) {
List<String> hostTags = _hostTagsDao.getHostTags(host.getId());
host.setHostTags(hostTags);
List<HostTagVO> hostTagVOList = _hostTagsDao.getHostTags(host.getId());
if (CollectionUtils.isNotEmpty(hostTagVOList)) {
List<String> hostTagList = hostTagVOList.parallelStream().map(HostTagVO::getTag).collect(Collectors.toList());
host.setHostTags(hostTagList, hostTagVOList.get(0).getIsTagARule());
} else {
host.setHostTags(null, null);
}
}
@DB
@ -881,10 +915,10 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected void saveHostTags(HostVO host) {
List<String> hostTags = host.getHostTags();
if (hostTags == null || (hostTags != null && hostTags.isEmpty())) {
if (CollectionUtils.isEmpty(hostTags)) {
return;
}
_hostTagsDao.persist(host.getId(), hostTags);
_hostTagsDao.persist(host.getId(), hostTags, host.getIsTagARule());
}
protected void saveGpuRecords(HostVO host) {
@ -1244,6 +1278,26 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return listBy(sc);
}
@Override
public List<HostVO> listAllHostsThatHaveNoRuleTag(Type type, Long clusterId, Long podId, Long dcId) {
SearchCriteria<HostVO> sc = searchBuilderFindByIdTypeClusterIdPodIdDcIdAndWithoutRuleTag.create();
if (type != null) {
sc.setParameters("type", type);
}
if (clusterId != null) {
sc.setParameters("cluster_id", clusterId);
}
if (podId != null) {
sc.setParameters("pod_id", podId);
}
if (dcId != null) {
sc.setParameters("data_center_id", dcId);
}
sc.setJoinParameters("id", "is_tag_a_rule", false);
return search(sc, null);
}
@Override
public List<Long> listClustersByHostTag(String computeOfferingTags) {
TransactionLegacy txn = TransactionLegacy.currentTxn();
@ -1266,9 +1320,6 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
result.add(rs.getLong(1));
}
pstmt.close();
if(result.isEmpty()){
throw new CloudRuntimeException("No suitable host found for follow compute offering tags: " + computeOfferingTags);
}
return result;
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + sql, e);
@ -1293,15 +1344,33 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
result.add(rs.getLong(1));
}
pstmt.close();
if(result.isEmpty()){
throw new CloudRuntimeException("No suitable host found for follow compute offering tags: " + computeOfferingTags);
}
return result;
} catch (SQLException e) {
throw new CloudRuntimeException("DB Exception on: " + select, e);
}
}
public List<HostVO> findHostsWithTagRuleThatMatchComputeOferringTags(String computeOfferingTags) {
List<HostTagVO> hostTagVOList = _hostTagsDao.findHostRuleTags();
List<HostVO> result = new ArrayList<>();
for (HostTagVO rule: hostTagVOList) {
if (TagAsRuleHelper.interpretTagAsRule(rule.getTag(), computeOfferingTags, HostTagsDao.hostTagRuleExecutionTimeout.value())) {
result.add(findById(rule.getHostId()));
}
}
return result;
}
public List<Long> findClustersThatMatchHostTagRule(String computeOfferingTags) {
Set<Long> result = new HashSet<>();
List<HostVO> hosts = findHostsWithTagRuleThatMatchComputeOferringTags(computeOfferingTags);
for (HostVO host: hosts) {
result.add(host.getClusterId());
}
return new ArrayList<>(result);
}
private String getHostIdsByComputeTags(List<String> offeringTags){
List<String> questionMarks = new ArrayList();
offeringTags.forEach((tag) -> { questionMarks.add("?"); });

View File

@ -20,15 +20,21 @@ import java.util.List;
import com.cloud.host.HostTagVO;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.framework.config.ConfigKey;
public interface HostTagsDao extends GenericDao<HostTagVO, Long> {
void persist(long hostId, List<String> hostTags);
ConfigKey<Long> hostTagRuleExecutionTimeout = new ConfigKey<>("Advanced", Long.class, "host.tag.rule.execution.timeout", "2000", "The maximum runtime, in milliseconds, " +
"to execute a host tag rule; if it is reached, a timeout will happen.", true);
List<String> getHostTags(long hostId);
void persist(long hostId, List<String> hostTags, Boolean isTagARule);
List<HostTagVO> getHostTags(long hostId);
List<String> getDistinctImplicitHostTags(List<Long> hostIds, String[] implicitHostTags);
void deleteTags(long hostId);
List<HostTagVO> findHostRuleTags();
}

View File

@ -16,10 +16,10 @@
// under the License.
package com.cloud.host.dao;
import java.util.ArrayList;
import java.util.List;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.springframework.stereotype.Component;
import com.cloud.host.HostTagVO;
@ -31,13 +31,14 @@ import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.db.SearchCriteria.Func;
@Component
public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements HostTagsDao {
public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements HostTagsDao, Configurable {
protected final SearchBuilder<HostTagVO> HostSearch;
protected final GenericSearchBuilder<HostTagVO, String> DistinctImplictTagsSearch;
public HostTagsDaoImpl() {
HostSearch = createSearchBuilder();
HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
HostSearch.and("isTagARule", HostSearch.entity().getIsTagARule(), SearchCriteria.Op.EQ);
HostSearch.done();
DistinctImplictTagsSearch = createSearchBuilder(String.class);
@ -48,17 +49,11 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
}
@Override
public List<String> getHostTags(long hostId) {
public List<HostTagVO> getHostTags(long hostId) {
SearchCriteria<HostTagVO> sc = HostSearch.create();
sc.setParameters("hostId", hostId);
List<HostTagVO> results = search(sc, null);
List<String> hostTags = new ArrayList<String>(results.size());
for (HostTagVO result : results) {
hostTags.add(result.getTag());
}
return hostTags;
return search(sc, null);
}
@Override
@ -80,7 +75,15 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
}
@Override
public void persist(long hostId, List<String> hostTags) {
public List<HostTagVO> findHostRuleTags() {
SearchCriteria<HostTagVO> sc = HostSearch.create();
sc.setParameters("isTagARule", true);
return search(sc, null);
}
@Override
public void persist(long hostId, List<String> hostTags, Boolean isTagARule) {
TransactionLegacy txn = TransactionLegacy.currentTxn();
txn.start();
@ -91,10 +94,20 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
for (String tag : hostTags) {
tag = tag.trim();
if (tag.length() > 0) {
HostTagVO vo = new HostTagVO(hostId, tag);
HostTagVO vo = new HostTagVO(hostId, tag, isTagARule);
persist(vo);
}
}
txn.commit();
}
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {hostTagRuleExecutionTimeout};
}
@Override
public String getConfigComponentName() {
return HostTagsDaoImpl.class.getSimpleName();
}
}

View File

@ -21,6 +21,7 @@ import java.util.List;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.network.IpAddress.State;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.net.Ip;
public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
@ -100,4 +101,6 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
List<IPAddressVO> listByDcIdAndAssociatedNetwork(long dcId);
List<IPAddressVO> listByNetworkId(long networkId);
void buildQuarantineSearchCriteria(SearchCriteria<IPAddressVO> sc);
}

View File

@ -24,6 +24,7 @@ import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.resourcedetail.dao.UserIpAddressDetailsDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -32,6 +33,7 @@ import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.network.IpAddress.State;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.utils.db.DB;
@ -69,6 +71,9 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
@Inject
UserIpAddressDetailsDao _detailsDao;
@Inject
PublicIpQuarantineDao publicIpQuarantineDao;
// make it public for JUnit test
public IPAddressDaoImpl() {
}
@ -534,4 +539,19 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
sc.setParameters("state", State.Allocated);
return listBy(sc);
}
@Override
public void buildQuarantineSearchCriteria(SearchCriteria<IPAddressVO> sc) {
long accountId = CallContext.current().getCallingAccount().getAccountId();
SearchBuilder<PublicIpQuarantineVO> listAllIpsInQuarantine = publicIpQuarantineDao.createSearchBuilder();
listAllIpsInQuarantine.and("quarantineEndDate", listAllIpsInQuarantine.entity().getEndDate(), SearchCriteria.Op.GT);
listAllIpsInQuarantine.and("previousOwnerId", listAllIpsInQuarantine.entity().getPreviousOwnerId(), Op.NEQ);
SearchCriteria<PublicIpQuarantineVO> searchCriteria = listAllIpsInQuarantine.create();
searchCriteria.setParameters("quarantineEndDate", new Date());
searchCriteria.setParameters("previousOwnerId", accountId);
Object[] quarantinedIpsIdsAllowedToUser = publicIpQuarantineDao.search(searchCriteria, null).stream().map(PublicIpQuarantineVO::getPublicIpAddressId).toArray();
sc.setParametersIfNotNull("quarantinedPublicIpsIdsNIN", quarantinedIpsIdsAllowedToUser);
}
}

View File

@ -29,7 +29,6 @@ import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import com.cloud.network.IpAddress;
import com.cloud.utils.db.GenericDao;
@ -97,14 +96,6 @@ public class IPAddressVO implements IpAddress {
@Column(name = "is_system")
private boolean system;
@Column(name = "account_id")
@Transient
private Long accountId = null;
@Transient
@Column(name = "domain_id")
private Long domainId = null;
@Column(name = "vpc_id")
private Long vpcId;

View File

@ -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 com.cloud.network.dao;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.utils.db.GenericDao;
public interface PublicIpQuarantineDao extends GenericDao<PublicIpQuarantineVO, Long> {
PublicIpQuarantineVO findByPublicIpAddressId(long publicIpAddressId);
PublicIpQuarantineVO findByIpAddress(String publicIpAddress);
}

View File

@ -0,0 +1,71 @@
// 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.network.dao;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
@Component
public class PublicIpQuarantineDaoImpl extends GenericDaoBase<PublicIpQuarantineVO, Long> implements PublicIpQuarantineDao {
private SearchBuilder<PublicIpQuarantineVO> publicIpAddressByIdSearch;
private SearchBuilder<IPAddressVO> ipAddressSearchBuilder;
@Inject
IPAddressDao ipAddressDao;
@PostConstruct
public void init() {
publicIpAddressByIdSearch = createSearchBuilder();
publicIpAddressByIdSearch.and("publicIpAddressId", publicIpAddressByIdSearch.entity().getPublicIpAddressId(), SearchCriteria.Op.EQ);
ipAddressSearchBuilder = ipAddressDao.createSearchBuilder();
ipAddressSearchBuilder.and("ipAddress", ipAddressSearchBuilder.entity().getAddress(), SearchCriteria.Op.EQ);
ipAddressSearchBuilder.and("removed", ipAddressSearchBuilder.entity().getRemoved(), SearchCriteria.Op.NULL);
publicIpAddressByIdSearch.join("quarantineJoin", ipAddressSearchBuilder, ipAddressSearchBuilder.entity().getId(),
publicIpAddressByIdSearch.entity().getPublicIpAddressId(), JoinBuilder.JoinType.INNER);
ipAddressSearchBuilder.done();
publicIpAddressByIdSearch.done();
}
@Override
public PublicIpQuarantineVO findByPublicIpAddressId(long publicIpAddressId) {
SearchCriteria<PublicIpQuarantineVO> sc = publicIpAddressByIdSearch.create();
sc.setParameters("publicIpAddressId", publicIpAddressId);
final Filter filter = new Filter(PublicIpQuarantineVO.class, "created", false);
return findOneBy(sc, filter);
}
@Override
public PublicIpQuarantineVO findByIpAddress(String publicIpAddress) {
SearchCriteria<PublicIpQuarantineVO> sc = publicIpAddressByIdSearch.create();
sc.setJoinParameters("quarantineJoin", "ipAddress", publicIpAddress);
final Filter filter = new Filter(PublicIpQuarantineVO.class, "created", false);
return findOneBy(sc, filter);
}
}

View File

@ -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 com.cloud.network.vo;
import com.cloud.network.PublicIpQuarantine;
import com.cloud.utils.db.GenericDao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date;
import java.util.UUID;
@Entity
@Table(name = "quarantined_ips")
public class PublicIpQuarantineVO implements PublicIpQuarantine {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "uuid", nullable = false)
private String uuid = UUID.randomUUID().toString();
@Column(name = "public_ip_address_id", nullable = false)
private Long publicIpAddressId;
@Column(name = "previous_owner_id", nullable = false)
private Long previousOwnerId;
@Column(name = GenericDao.CREATED_COLUMN, nullable = false)
@Temporal(value = TemporalType.TIMESTAMP)
private Date created;
@Column(name = GenericDao.REMOVED_COLUMN)
@Temporal(value = TemporalType.TIMESTAMP)
private Date removed = null;
@Column(name = "end_date", nullable = false)
@Temporal(value = TemporalType.TIMESTAMP)
private Date endDate;
@Column(name = "removal_reason")
private String removalReason = null;
public PublicIpQuarantineVO() {
}
public PublicIpQuarantineVO(Long publicIpAddressId, Long previousOwnerId, Date created, Date endDate) {
this.publicIpAddressId = publicIpAddressId;
this.previousOwnerId = previousOwnerId;
this.created = created;
this.endDate = endDate;
}
@Override
public long getId() {
return id;
}
@Override
public Long getPublicIpAddressId() {
return publicIpAddressId;
}
@Override
public Long getPreviousOwnerId() {
return previousOwnerId;
}
@Override
public Date getEndDate() {
return endDate;
}
@Override
public String getRemovalReason() {
return removalReason;
}
@Override
public String getUuid() {
return uuid;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public void setRemovalReason(String removalReason) {
this.removalReason = removalReason;
}
@Override
public Date getRemoved() {
return removed;
}
public void setRemoved(Date removed) {
this.removed = removed;
}
@Override
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
}

View File

@ -17,6 +17,8 @@
package com.cloud.network.vpc;
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
import java.util.UUID;
import javax.persistence.Column;
@ -85,6 +87,11 @@ public class NetworkACLVO implements NetworkACL {
return name;
}
@Override
public String toString() {
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "uuid", "name", "vpcId");
}
public void setUuid(String uuid) {
this.uuid = uuid;
}

View File

@ -0,0 +1,257 @@
// 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.storage;
import com.cloud.utils.db.GenericDao;
import com.google.gson.annotations.Expose;
import org.apache.cloudstack.storage.object.Bucket;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
import java.util.UUID;
@Entity
@Table(name = "bucket")
public class BucketVO implements Bucket {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "account_id")
long accountId;
@Column(name = "domain_id")
long domainId;
@Column(name = "object_store_id")
long objectStoreId;
@Expose
@Column(name = "name")
String name;
@Expose
@Column(name = "state", updatable = true, nullable = false)
@Enumerated(value = EnumType.STRING)
private State state;
@Column(name = "size")
Long size;
@Column(name = "quota")
Integer quota;
@Column(name = "versioning")
boolean versioning;
@Column(name = "encryption")
boolean encryption;
@Column(name = "object_lock")
boolean objectLock;
@Column(name = "policy")
String policy;
@Column(name = "bucket_url")
String bucketURL;
@Column(name = "access_key")
String accessKey;
@Column(name = "secret_key")
String secretKey;
@Column(name = GenericDao.CREATED_COLUMN)
Date created;
@Column(name = GenericDao.REMOVED_COLUMN)
Date removed;
@Column(name = "uuid")
String uuid;
public BucketVO() {
}
public BucketVO(long accountId, long domainId, long objectStoreId, String name, Integer quota, boolean versioning,
boolean encryption, boolean objectLock, String policy)
{
this.accountId = accountId;
this.domainId = domainId;
this.objectStoreId = objectStoreId;
this.name = name;
state = State.Allocated;
uuid = UUID.randomUUID().toString();
this.quota = quota;
this.versioning = versioning;
this.encryption = encryption;
this.objectLock = objectLock;
this.policy = policy;
this.size = 0L;
}
@Override
public long getId() {
return id;
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public long getDomainId() {
return domainId;
}
@Override
public long getObjectStoreId() {
return objectStoreId;
}
@Override
public String getName() {
return name;
}
public Long getSize() {
return size;
}
@Override
public Date getCreated() {
return created;
}
public Date getRemoved() {
return removed;
}
@Override
public State getState() {
return state;
}
@Override
public void setName(String name) {
this.name = name;
}
public void setState(State state) {
this.state = state;
}
@Override
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Integer getQuota() {
return quota;
}
public void setQuota(Integer quota) {
this.quota = quota;
}
public boolean isVersioning() {
return versioning;
}
public void setVersioning(boolean versioning) {
this.versioning = versioning;
}
public boolean isEncryption() {
return encryption;
}
public void setEncryption(boolean encryption) {
this.encryption = encryption;
}
public boolean isObjectLock() {
return objectLock;
}
public void setObjectLock(boolean objectLock) {
this.objectLock = objectLock;
}
public String getPolicy() {
return policy;
}
public void setPolicy(String policy) {
this.policy = policy;
}
public String getBucketURL() {
return bucketURL;
}
public void setBucketURL(String bucketURL) {
this.bucketURL = bucketURL;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public void setSize(Long size) {
this.size = size;
}
@Override
public Class<?> getEntityType() {
return Bucket.class;
}
@Override
public String toString() {
return String.format("Bucket %s", new ToStringBuilder(this, ToStringStyle.JSON_STYLE).append("uuid", getUuid()).append("name", getName())
.append("ObjectStoreId", getObjectStoreId()).toString());
}
}

View File

@ -23,7 +23,9 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.utils.NumbersUtil;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.commons.lang3.BooleanUtils;
@Entity
@Table(name = "storage_pool_tags")
@ -43,9 +45,19 @@ public class StoragePoolTagVO implements InternalIdentity {
@Column(name = "tag")
private String tag;
@Column(name = "is_tag_a_rule")
private boolean isTagARule;
public StoragePoolTagVO(long poolId, String tag) {
this.poolId = poolId;
this.tag = tag;
this.isTagARule = false;
}
public StoragePoolTagVO(long poolId, String tag, Boolean isTagARule) {
this.poolId = poolId;
this.tag = tag;
this.isTagARule = BooleanUtils.toBooleanDefaultIfNull(isTagARule, false);
}
@Override
@ -61,4 +73,20 @@ public class StoragePoolTagVO implements InternalIdentity {
return tag;
}
public boolean isTagARule() {
return this.isTagARule;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof StoragePoolTagVO) {
return this.poolId == ((StoragePoolTagVO)obj).getPoolId();
}
return false;
}
@Override
public int hashCode() {
return NumbersUtil.hash(id);
}
}

View File

@ -0,0 +1,30 @@
// 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.storage.dao;
import com.cloud.storage.BucketVO;
import com.cloud.utils.db.GenericDao;
import java.util.List;
public interface BucketDao extends GenericDao<BucketVO, Long> {
List<BucketVO> listByObjectStoreId(long objectStoreId);
List<BucketVO> listByObjectStoreIdAndAccountId(long objectStoreId, long accountId);
List<BucketVO> searchByIds(Long[] ids);
}

Some files were not shown because too many files have changed in this diff Show More