mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CloudStack Backup & Recovery Framework (#3553)
This commit is contained in:
parent
4e3f7c2d65
commit
318924d801
@ -46,6 +46,7 @@ env:
|
||||
smoke/test_affinity_groups
|
||||
smoke/test_affinity_groups_projects
|
||||
smoke/test_async_job
|
||||
smoke/test_backup_recovery_dummy
|
||||
smoke/test_create_list_domain_account_project
|
||||
smoke/test_create_network
|
||||
smoke/test_deploy_vgpu_enabled_vm
|
||||
|
||||
@ -478,6 +478,17 @@ public class EventTypes {
|
||||
public static final String EVENT_VM_SNAPSHOT_OFF_PRIMARY = "VMSNAPSHOT.OFF_PRIMARY";
|
||||
public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
|
||||
|
||||
// Backup and Recovery events
|
||||
public static final String EVENT_VM_BACKUP_IMPORT_OFFERING = "BACKUP.IMPORT.OFFERING";
|
||||
public static final String EVENT_VM_BACKUP_OFFERING_ASSIGN = "BACKUP.OFFERING.ASSIGN";
|
||||
public static final String EVENT_VM_BACKUP_OFFERING_REMOVE = "BACKUP.OFFERING.REMOVE";
|
||||
public static final String EVENT_VM_BACKUP_CREATE = "BACKUP.CREATE";
|
||||
public static final String EVENT_VM_BACKUP_RESTORE = "BACKUP.RESTORE";
|
||||
public static final String EVENT_VM_BACKUP_DELETE = "BACKUP.DELETE";
|
||||
public static final String EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM = "BACKUP.RESTORE.VOLUME.TO.VM";
|
||||
public static final String EVENT_VM_BACKUP_SCHEDULE_CONFIGURE = "BACKUP.SCHEDULE.CONFIGURE";
|
||||
public static final String EVENT_VM_BACKUP_SCHEDULE_DELETE = "BACKUP.SCHEDULE.DELETE";
|
||||
|
||||
// external network device events
|
||||
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
|
||||
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_DELETE = "PHYSICAL.NVPCONTROLLER.DELETE";
|
||||
|
||||
@ -19,13 +19,14 @@ package com.cloud.hypervisor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.storage.StoragePool;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.vm.NicProfile;
|
||||
@ -86,6 +87,11 @@ public interface HypervisorGuru extends Adapter {
|
||||
|
||||
Map<String, String> getClusterSettings(long vmId);
|
||||
|
||||
VirtualMachine importVirtualMachineFromBackup(long zoneId, long domainId, long accountId, long userId,
|
||||
String vmInternalName, Backup backup) throws Exception;
|
||||
|
||||
boolean attachRestoredVolumeToVirtualMachine(long zoneId, String location, Backup.VolumeInfo volumeInfo,
|
||||
VirtualMachine vm, long poolId, Backup backup) throws Exception;
|
||||
/**
|
||||
* Will generate commands to migrate a vm to a pool. For now this will only work for stopped VMs on Vmware.
|
||||
*
|
||||
|
||||
@ -29,6 +29,7 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
||||
ISO(true, false),
|
||||
Volume(true, true),
|
||||
Snapshot(true, false),
|
||||
Backup(true, false),
|
||||
Network(true, true),
|
||||
Nic(false, true),
|
||||
LoadBalancer(true, true),
|
||||
|
||||
@ -16,18 +16,21 @@
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Displayable;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.kernel.Partition;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.utils.fsm.StateMachine2.Transition;
|
||||
import com.cloud.utils.fsm.StateMachine2.Transition.Impact;
|
||||
import com.cloud.utils.fsm.StateObject;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Displayable;
|
||||
import org.apache.cloudstack.kernel.Partition;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* VirtualMachine describes the properties held by a virtual machine
|
||||
@ -319,6 +322,12 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Partition,
|
||||
|
||||
Long getDiskOfferingId();
|
||||
|
||||
Long getBackupOfferingId();
|
||||
|
||||
String getBackupExternalId();
|
||||
|
||||
List<Backup.VolumeInfo> getBackupVolumeList();
|
||||
|
||||
Type getType();
|
||||
|
||||
HypervisorType getHypervisorType();
|
||||
|
||||
@ -23,6 +23,7 @@ public enum ApiCommandJobType {
|
||||
Volume,
|
||||
ConsoleProxy,
|
||||
Snapshot,
|
||||
Backup,
|
||||
Template,
|
||||
Iso,
|
||||
SystemVm,
|
||||
|
||||
@ -33,6 +33,9 @@ public class ApiConstants {
|
||||
public static final String APPLIED = "applied";
|
||||
public static final String LIST_LB_VMIPS = "lbvmips";
|
||||
public static final String AVAILABLE = "available";
|
||||
public static final String BACKUP_ID = "backupid";
|
||||
public static final String BACKUP_OFFERING_NAME = "backupofferingname";
|
||||
public static final String BACKUP_OFFERING_ID = "backupofferingid";
|
||||
public static final String BITS = "bits";
|
||||
public static final String BOOTABLE = "bootable";
|
||||
public static final String BIND_DN = "binddn";
|
||||
@ -144,6 +147,7 @@ public class ApiConstants {
|
||||
public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
|
||||
public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
|
||||
public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
|
||||
public static final String EXTERNAL = "external";
|
||||
public static final String FENCE = "fence";
|
||||
public static final String FETCH_LATEST = "fetchlatest";
|
||||
public static final String FIRSTNAME = "firstname";
|
||||
@ -366,6 +370,7 @@ public class ApiConstants {
|
||||
public static final String VALUE = "value";
|
||||
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
|
||||
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
|
||||
public static final String VIRTUAL_MACHINE_NAME = "virtualmachinename";
|
||||
public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
|
||||
public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
|
||||
public static final String USAGE_ID = "usageid";
|
||||
@ -385,6 +390,7 @@ public class ApiConstants {
|
||||
public static final String VNET = "vnet";
|
||||
public static final String IS_VOLATILE = "isvolatile";
|
||||
public static final String VOLUME_ID = "volumeid";
|
||||
public static final String VOLUMES = "volumes";
|
||||
public static final String ZONE = "zone";
|
||||
public static final String ZONE_ID = "zoneid";
|
||||
public static final String ZONE_NAME = "zonename";
|
||||
@ -531,6 +537,7 @@ public class ApiConstants {
|
||||
public static final String REQUIRED = "required";
|
||||
public static final String RESTART_REQUIRED = "restartrequired";
|
||||
public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
|
||||
public static final String ALLOW_USER_DRIVEN_BACKUPS = "allowuserdrivenbackups";
|
||||
public static final String CONSERVE_MODE = "conservemode";
|
||||
public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
|
||||
public static final String KEYWORD = "keyword";
|
||||
@ -780,7 +787,7 @@ public class ApiConstants {
|
||||
}
|
||||
|
||||
public enum VMDetails {
|
||||
all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp;
|
||||
all, group, nics, stats, secgrp, tmpl, servoff, diskoff, backoff, iso, volume, min, affgrp;
|
||||
}
|
||||
|
||||
public enum DomainDetails {
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
// 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
public abstract class BaseBackupListCmd extends BaseListCmd {
|
||||
|
||||
protected void setupResponseBackupOfferingsList(final List<BackupOffering> offerings, final Integer count) {
|
||||
final ListResponse<BackupOfferingResponse> response = new ListResponse<>();
|
||||
final List<BackupOfferingResponse> responses = new ArrayList<>();
|
||||
for (final BackupOffering offering : offerings) {
|
||||
if (offering == null) {
|
||||
continue;
|
||||
}
|
||||
BackupOfferingResponse backupOfferingResponse = _responseGenerator.createBackupOfferingResponse(offering);
|
||||
responses.add(backupOfferingResponse);
|
||||
}
|
||||
response.setResponses(responses, count);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
@ -22,8 +22,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.management.ManagementServerHost;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
||||
@ -36,6 +34,8 @@ import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
|
||||
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
|
||||
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.CapacityResponse;
|
||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.ConditionResponse;
|
||||
@ -88,6 +88,7 @@ import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceCountResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
@ -111,6 +112,7 @@ import org.apache.cloudstack.api.response.UpgradeRouterTemplateResponse;
|
||||
import org.apache.cloudstack.api.response.UsageRecordResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
|
||||
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
|
||||
@ -119,7 +121,11 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.api.response.VpnUsersResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.config.Configuration;
|
||||
import org.apache.cloudstack.management.ManagementServerHost;
|
||||
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
|
||||
import org.apache.cloudstack.region.PortableIp;
|
||||
import org.apache.cloudstack.region.PortableIpRange;
|
||||
@ -467,6 +473,12 @@ public interface ResponseGenerator {
|
||||
|
||||
SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
|
||||
|
||||
BackupResponse createBackupResponse(Backup backup);
|
||||
|
||||
BackupScheduleResponse createBackupScheduleResponse(BackupSchedule backup);
|
||||
|
||||
BackupOfferingResponse createBackupOfferingResponse(BackupOffering policy);
|
||||
|
||||
ManagementServerResponse createManagementResponse(ManagementServerHost mgmt);
|
||||
|
||||
List<RouterHealthCheckResultResponse> createHealthCheckResponse(VirtualMachine router, List<RouterHealthCheckResult> healthCheckResults);
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
|
||||
@APICommand(name = DeleteBackupOfferingCmd.APINAME,
|
||||
description = "Deletes a backup offering",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class DeleteBackupOfferingCmd extends BaseCmd {
|
||||
public static final String APINAME = "deleteBackupOffering";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupOfferingResponse.class,
|
||||
required = true,
|
||||
description = "ID of the backup offering")
|
||||
private Long id;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
if (backupManager.deleteBackupOffering(getId())) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to remove backup offering: " + getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = ImportBackupOfferingCmd.APINAME,
|
||||
description = "Imports a backup offering using a backup provider",
|
||||
responseObject = BackupOfferingResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class ImportBackupOfferingCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "importBackupOffering";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true,
|
||||
description = "the name of the backup offering")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true,
|
||||
description = "the description of the backup offering")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.EXTERNAL_ID,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "The backup offering ID (from backup provider side)")
|
||||
private String externalId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "The zone ID", required = true)
|
||||
private Long zoneId;
|
||||
|
||||
@Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = CommandType.BOOLEAN,
|
||||
description = "Whether users are allowed to create adhoc backups and backup schedules", required = true)
|
||||
private Boolean userDrivenBackups;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Boolean getUserDrivenBackups() {
|
||||
return userDrivenBackups == null ? false : userDrivenBackups;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
BackupOffering policy = backupManager.importBackupOffering(this);
|
||||
if (policy != null) {
|
||||
BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(policy);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add a backup offering");
|
||||
}
|
||||
} catch (InvalidParameterValueException e) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
|
||||
} catch (CloudRuntimeException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_IMPORT_OFFERING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Importing backup offering: " + name + " (external ID: " + externalId + ") on zone ID " + zoneId ;
|
||||
}
|
||||
}
|
||||
@ -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.admin.backup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseBackupListCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = ListBackupProviderOfferingsCmd.APINAME,
|
||||
description = "Lists external backup offerings of the provider",
|
||||
responseObject = BackupOfferingResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class ListBackupProviderOfferingsCmd extends BaseBackupListCmd {
|
||||
public static final String APINAME = "listBackupProviderOfferings";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
required = true, description = "The zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
private void validateParameters() {
|
||||
if (getZoneId() == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please provide a valid zone ID ");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, ServerApiException, ConcurrentOperationException {
|
||||
validateParameters();
|
||||
try {
|
||||
final List<BackupOffering> backupOfferings = backupManager.listBackupProviderOfferings(getZoneId());
|
||||
setupResponseBackupOfferingsList(backupOfferings, backupOfferings.size());
|
||||
} catch (InvalidParameterValueException e) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
|
||||
} catch (CloudRuntimeException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.backup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.BackupProviderResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupProvider;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = ListBackupProvidersCmd.APINAME,
|
||||
description = "Lists Backup and Recovery providers",
|
||||
responseObject = BackupProviderResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class ListBackupProvidersCmd extends BaseCmd {
|
||||
public static final String APINAME = "listBackupProviders";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List Backup and Recovery provider by name")
|
||||
private String name;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
private void setupResponse(final List<BackupProvider> providers) {
|
||||
final ListResponse<BackupProviderResponse> response = new ListResponse<>();
|
||||
final List<BackupProviderResponse> responses = new ArrayList<>();
|
||||
for (final BackupProvider provider : providers) {
|
||||
if (provider == null || (getName() != null && !provider.getName().equals(getName()))) {
|
||||
continue;
|
||||
}
|
||||
final BackupProviderResponse backupProviderResponse = new BackupProviderResponse();
|
||||
backupProviderResponse.setName(provider.getName());
|
||||
backupProviderResponse.setDescription(provider.getDescription());
|
||||
backupProviderResponse.setObjectName("providers");
|
||||
responses.add(backupProviderResponse);
|
||||
}
|
||||
response.setResponses(responses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<BackupProvider> providers = backupManager.listBackupProviders();
|
||||
setupResponse(providers);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
|
||||
@APICommand(name = AssignVirtualMachineToBackupOfferingCmd.APINAME,
|
||||
description = "Assigns a VM to a backup offering",
|
||||
responseObject = BackupResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class AssignVirtualMachineToBackupOfferingCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "assignVirtualMachineToBackupOffering";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the virtual machine")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.BACKUP_OFFERING_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupOfferingResponse.class,
|
||||
required = true,
|
||||
description = "ID of the backup offering")
|
||||
private Long offeringId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getOfferingId() {
|
||||
return offeringId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.assignVMToBackupOffering(getVmId(), getOfferingId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add VM to backup offering");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_OFFERING_ASSIGN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Assigning VM to backup offering ID: " + offeringId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = CreateBackupCmd.APINAME,
|
||||
description = "Create VM backup",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateBackupCmd extends BaseAsyncCreateCmd {
|
||||
public static final String APINAME = "createBackup";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the VM")
|
||||
private Long vmId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.createBackup(getVmId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Error while creating backup of VM");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiCommandJobType getInstanceType() {
|
||||
return ApiCommandJobType.Backup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_CREATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Creating backup for VM " + vmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() throws ResourceAllocationException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getEntityId() {
|
||||
return vmId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,128 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = CreateBackupScheduleCmd.APINAME,
|
||||
description = "Creates a user-defined VM backup schedule",
|
||||
responseObject = BackupResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class CreateBackupScheduleCmd extends BaseCmd {
|
||||
public static final String APINAME = "createBackupSchedule";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the VM for which schedule is to be defined")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.INTERVAL_TYPE,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "valid values are HOURLY, DAILY, WEEKLY, and MONTHLY")
|
||||
private String intervalType;
|
||||
|
||||
@Parameter(name = ApiConstants.SCHEDULE,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "custom backup schedule, the format is:"
|
||||
+ "for HOURLY MM*, for DAILY MM:HH*, for WEEKLY MM:HH:DD (1-7)*, for MONTHLY MM:HH:DD (1-28)")
|
||||
private String schedule;
|
||||
|
||||
@Parameter(name = ApiConstants.TIMEZONE,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "Specifies a timezone for this command. For more information on the timezone parameter, see TimeZone Format.")
|
||||
private String timezone;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public DateUtil.IntervalType getIntervalType() {
|
||||
return DateUtil.IntervalType.getIntervalType(intervalType);
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ServerApiException {
|
||||
try {
|
||||
BackupSchedule schedule = backupManager.configureBackupSchedule(this);
|
||||
if (schedule != null) {
|
||||
BackupScheduleResponse response = _responseGenerator.createBackupScheduleResponse(schedule);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Error while creating backup schedule of VM");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = DeleteBackupCmd.APINAME,
|
||||
description = "Delete VM backup",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeleteBackupCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "deleteBackup";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
required = true,
|
||||
description = "id of the VM backup")
|
||||
private Long backupId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.deleteBackup(backupId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Error while deleting backup of VM");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Deleting backup ID " + backupId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = DeleteBackupScheduleCmd.APINAME,
|
||||
description = "Deletes the backup schedule of a VM",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeleteBackupScheduleCmd extends BaseCmd {
|
||||
public static final String APINAME = "deleteBackupSchedule";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the VM")
|
||||
private Long vmId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.deleteBackupSchedule(getVmId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to delete VM backup schedule");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseBackupListCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = ListBackupOfferingsCmd.APINAME,
|
||||
description = "Lists backup offerings",
|
||||
responseObject = BackupOfferingResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListBackupOfferingsCmd extends BaseBackupListCmd {
|
||||
public static final String APINAME = "listBackupOfferings";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = BackupOfferingResponse.class,
|
||||
description = "The backup offering ID")
|
||||
private Long offeringId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
|
||||
description = "The zone ID")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Long getOfferingId() {
|
||||
return offeringId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, ServerApiException, ConcurrentOperationException {
|
||||
try {
|
||||
Pair<List<BackupOffering>, Integer> result = backupManager.listBackupOfferings(this);
|
||||
setupResponseBackupOfferingsList(result.first(), result.second());
|
||||
} catch (InvalidParameterValueException e) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
|
||||
} catch (CloudRuntimeException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
}
|
||||
@ -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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = ListBackupScheduleCmd.APINAME,
|
||||
description = "List backup schedule of a VM",
|
||||
responseObject = BackupScheduleResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListBackupScheduleCmd extends BaseCmd {
|
||||
public static final String APINAME = "listBackupSchedule";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the VM")
|
||||
private Long vmId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try{
|
||||
BackupSchedule schedule = backupManager.listBackupSchedule(getVmId());
|
||||
if (schedule != null) {
|
||||
BackupScheduleResponse response = _responseGenerator.createBackupScheduleResponse(schedule);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("No backup schedule exists for the VM");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
@APICommand(name = ListBackupsCmd.APINAME,
|
||||
description = "Lists VM backups",
|
||||
responseObject = BackupResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListBackupsCmd extends BaseListProjectAndAccountResourcesCmd {
|
||||
public static final String APINAME = "listBackups";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
description = "id of the backup")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
description = "id of the VM")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ZoneResponse.class,
|
||||
description = "list backups by zone id")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
protected void setupResponseBackupList(final List<Backup> backups, final Integer count) {
|
||||
final List<BackupResponse> responses = new ArrayList<>();
|
||||
for (Backup backup : backups) {
|
||||
if (backup == null) {
|
||||
continue;
|
||||
}
|
||||
BackupResponse backupResponse = _responseGenerator.createBackupResponse(backup);
|
||||
responses.add(backupResponse);
|
||||
}
|
||||
final ListResponse<BackupResponse> response = new ListResponse<>();
|
||||
response.setResponses(responses, count);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try{
|
||||
Pair<List<Backup>, Integer> result = backupManager.listBackups(this);
|
||||
setupResponseBackupList(result.first(), result.second());
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
|
||||
@APICommand(name = RemoveVirtualMachineFromBackupOfferingCmd.APINAME,
|
||||
description = "Removes a VM from any existing backup offering",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RemoveVirtualMachineFromBackupOfferingCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "removeVirtualMachineFromBackupOffering";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "ID of the virtual machine")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.FORCED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "Whether to force remove VM from the backup offering that may also delete VM backups.")
|
||||
private Boolean forced;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public boolean getForced() {
|
||||
return forced == null ? false : forced;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.removeVMFromBackupOffering(getVmId(), getForced());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VM from backup offering");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_OFFERING_REMOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Removing VM ID" + vmId + " from backup offering";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = RestoreBackupCmd.APINAME,
|
||||
description = "Restores an existing stopped or deleted VM using a VM backup",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RestoreBackupCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "restoreBackup";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
required = true,
|
||||
description = "ID of the backup")
|
||||
private Long backupId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackup(backupId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Error while restoring VM from backup");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_RESTORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Restoring VM from backup: " + backupId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
// 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.backup;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.backup.BackupManager;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = RestoreVolumeFromBackupAndAttachToVMCmd.APINAME,
|
||||
description = "Restore and attach a backed up volume to VM",
|
||||
responseObject = SuccessResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class RestoreVolumeFromBackupAndAttachToVMCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "restoreVolumeFromBackupAndAttachToVM";
|
||||
|
||||
@Inject
|
||||
private BackupManager backupManager;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.BACKUP_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = BackupResponse.class,
|
||||
required = true,
|
||||
description = "ID of the VM backup")
|
||||
private Long backupId;
|
||||
|
||||
@Parameter(name = ApiConstants.VOLUME_ID,
|
||||
type = CommandType.STRING,
|
||||
required = true,
|
||||
description = "ID of the volume backed up")
|
||||
private String volumeUuid;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserVmResponse.class,
|
||||
required = true,
|
||||
description = "id of the VM where to attach the restored volume")
|
||||
private Long vmId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getVolumeUuid() {
|
||||
return volumeUuid;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getBackupId() {
|
||||
return backupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
try {
|
||||
boolean result = backupManager.restoreBackupVolumeAndAttachToVM(volumeUuid, backupId, vmId);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} else {
|
||||
throw new CloudRuntimeException("Error restoring volume and attaching to VM");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_BACKUP_RESTORE_VOLUME_TO_VM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Restoring volume "+ volumeUuid + " from backup " + backupId + " and attaching it to VM " + vmId;
|
||||
}
|
||||
}
|
||||
@ -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.api.command.user.backup;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
|
||||
@APICommand(name = UpdateBackupScheduleCmd.APINAME,
|
||||
description = "Updates a user-defined VM backup schedule",
|
||||
responseObject = BackupResponse.class, since = "4.14.0",
|
||||
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class UpdateBackupScheduleCmd extends CreateBackupScheduleCmd {
|
||||
public static final String APINAME = "updateBackupSchedule";
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
// 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 java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = BackupOffering.class)
|
||||
public class BackupOfferingResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "ID of the backup offering")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "name for the backup offering")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "description for the backup offering")
|
||||
private String description;
|
||||
|
||||
@SerializedName(ApiConstants.EXTERNAL_ID)
|
||||
@Param(description = "external ID on the provider side")
|
||||
private String externalId;
|
||||
|
||||
@SerializedName(ApiConstants.ALLOW_USER_DRIVEN_BACKUPS)
|
||||
@Param(description = "whether offering allows user driven ad-hoc/scheduled backups")
|
||||
private Boolean userDrivenBackups;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "zone ID")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_NAME)
|
||||
@Param(description = "zone name")
|
||||
private String zoneName;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the date this backup offering was created")
|
||||
private Date created;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setUserDrivenBackups(Boolean userDrivenBackups) {
|
||||
this.userDrivenBackups = userDrivenBackups;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public void setZoneName(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
// 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 org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.BackupProvider;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(BackupProvider.class)
|
||||
public class BackupProviderResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the CA service provider name")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the CA service provider")
|
||||
private String description;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,246 @@
|
||||
// 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 org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = Backup.class)
|
||||
public class BackupResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "ID of the VM backup")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
|
||||
@Param(description = "ID of the VM")
|
||||
private String vmId;
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_MACHINE_NAME)
|
||||
@Param(description = "name of the VM")
|
||||
private String vmName;
|
||||
|
||||
@SerializedName(ApiConstants.EXTERNAL_ID)
|
||||
@Param(description = "external backup id")
|
||||
private String externalId;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "backup type")
|
||||
private String type;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "backup date")
|
||||
private String date;
|
||||
|
||||
@SerializedName(ApiConstants.SIZE)
|
||||
@Param(description = "backup size in bytes")
|
||||
private Long size;
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_SIZE)
|
||||
@Param(description = "backup protected (virtual) size in bytes")
|
||||
private Long protectedSize;
|
||||
|
||||
@SerializedName(ApiConstants.STATUS)
|
||||
@Param(description = "backup status")
|
||||
private Backup.Status status;
|
||||
|
||||
@SerializedName(ApiConstants.VOLUMES)
|
||||
@Param(description = "backed up volumes")
|
||||
private String volumes;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_OFFERING_ID)
|
||||
@Param(description = "backup offering id")
|
||||
private String backupOfferingId;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_OFFERING_NAME)
|
||||
@Param(description = "backup offering name")
|
||||
private String backupOfferingName;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_ID)
|
||||
@Param(description = "account id")
|
||||
private String accountId;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "account name")
|
||||
private String account;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "domain id")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "domain name")
|
||||
private String domain;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "zone id")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE)
|
||||
@Param(description = "zone name")
|
||||
private String zone;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(String vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public void setVmName(String vmName) {
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Long getProtectedSize() {
|
||||
return protectedSize;
|
||||
}
|
||||
|
||||
public void setProtectedSize(Long protectedSize) {
|
||||
this.protectedSize = protectedSize;
|
||||
}
|
||||
|
||||
public Backup.Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Backup.Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getVolumes() {
|
||||
return volumes;
|
||||
}
|
||||
|
||||
public void setVolumes(String volumes) {
|
||||
this.volumes = volumes;
|
||||
}
|
||||
|
||||
public String getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public void setBackupOfferingId(String backupOfferingId) {
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
}
|
||||
|
||||
public String getBackupOffering() {
|
||||
return backupOfferingName;
|
||||
}
|
||||
|
||||
public void setBackupOffering(String backupOfferingName) {
|
||||
this.backupOfferingName = backupOfferingName;
|
||||
}
|
||||
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(String account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public String getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public String getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
public void setZone(String zone) {
|
||||
this.zone = zone;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
// 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 org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = Backup.RestorePoint.class)
|
||||
public class BackupRestorePointResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "external id of the restore point")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "created time")
|
||||
private String created;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "restore point type")
|
||||
private String type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
// 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 org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = BackupSchedule.class)
|
||||
public class BackupScheduleResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_MACHINE_NAME)
|
||||
@Param(description = "name of the VM")
|
||||
private String vmName;
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
|
||||
@Param(description = "ID of the VM")
|
||||
private String vmId;
|
||||
|
||||
@SerializedName("schedule")
|
||||
@Param(description = "time the backup is scheduled to be taken.")
|
||||
private String schedule;
|
||||
|
||||
@SerializedName("intervaltype")
|
||||
@Param(description = "the interval type of the backup schedule")
|
||||
private DateUtil.IntervalType intervalType;
|
||||
|
||||
@SerializedName("timezone")
|
||||
@Param(description = "the time zone of the backup schedule")
|
||||
private String timezone;
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public void setVmName(String vmName) {
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public String getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(String vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public void setSchedule(String schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
|
||||
public DateUtil.IntervalType getIntervalType() {
|
||||
return intervalType;
|
||||
}
|
||||
|
||||
public void setIntervalType(DateUtil.IntervalType intervalType) {
|
||||
this.intervalType = intervalType;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
}
|
||||
@ -156,6 +156,14 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
@Param(description = "the name of the disk offering of the virtual machine", since = "4.4")
|
||||
private String diskOfferingName;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_OFFERING_ID)
|
||||
@Param(description = "the ID of the backup offering of the virtual machine", since = "4.14")
|
||||
private String backupOfferingId;
|
||||
|
||||
@SerializedName(ApiConstants.BACKUP_OFFERING_NAME)
|
||||
@Param(description = "the name of the backup offering of the virtual machine", since = "4.14")
|
||||
private String backupOfferingName;
|
||||
|
||||
@SerializedName("forvirtualnetwork")
|
||||
@Param(description = "the virtual network for the service offering")
|
||||
private Boolean forVirtualNetwork;
|
||||
@ -439,6 +447,14 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
return diskOfferingName;
|
||||
}
|
||||
|
||||
public String getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public String getBackupOfferingName() {
|
||||
return backupOfferingName;
|
||||
}
|
||||
|
||||
public Boolean getForVirtualNetwork() {
|
||||
return forVirtualNetwork;
|
||||
}
|
||||
@ -697,6 +713,14 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
|
||||
this.diskOfferingName = diskOfferingName;
|
||||
}
|
||||
|
||||
public void setBackupOfferingId(String backupOfferingId) {
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
}
|
||||
|
||||
public void setBackupOfferingName(String backupOfferingName) {
|
||||
this.backupOfferingName = backupOfferingName;
|
||||
}
|
||||
|
||||
public void setCpuNumber(Integer cpuNumber) {
|
||||
this.cpuNumber = cpuNumber;
|
||||
}
|
||||
|
||||
142
api/src/main/java/org/apache/cloudstack/backup/Backup.java
Normal file
142
api/src/main/java/org/apache/cloudstack/backup/Backup.java
Normal file
@ -0,0 +1,142 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.utils.StringUtils;
|
||||
|
||||
public interface Backup extends ControlledEntity, InternalIdentity, Identity {
|
||||
|
||||
enum Status {
|
||||
Allocated, Queued, BackingUp, BackedUp, Error, Failed, Restoring, Removed, Expunged
|
||||
}
|
||||
|
||||
class Metric {
|
||||
private Long backupSize = 0L;
|
||||
private Long dataSize = 0L;
|
||||
|
||||
public Metric(final Long backupSize, final Long dataSize) {
|
||||
this.backupSize = backupSize;
|
||||
this.dataSize = dataSize;
|
||||
}
|
||||
|
||||
public Long getBackupSize() {
|
||||
return backupSize;
|
||||
}
|
||||
|
||||
public Long getDataSize() {
|
||||
return dataSize;
|
||||
}
|
||||
|
||||
public void setBackupSize(Long backupSize) {
|
||||
this.backupSize = backupSize;
|
||||
}
|
||||
|
||||
public void setDataSize(Long dataSize) {
|
||||
this.dataSize = dataSize;
|
||||
}
|
||||
}
|
||||
|
||||
class RestorePoint {
|
||||
private String id;
|
||||
private String created;
|
||||
private String type;
|
||||
|
||||
public RestorePoint(String id, String created, String type) {
|
||||
this.id = id;
|
||||
this.created = created;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
class VolumeInfo {
|
||||
private String uuid;
|
||||
private Volume.Type type;
|
||||
private Long size;
|
||||
private String path;
|
||||
|
||||
public VolumeInfo(String uuid, String path, Volume.Type type, Long size) {
|
||||
this.uuid = uuid;
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public Volume.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Volume.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return StringUtils.join(":", uuid, path, type, size);
|
||||
}
|
||||
}
|
||||
|
||||
long getVmId();
|
||||
String getExternalId();
|
||||
String getType();
|
||||
String getDate();
|
||||
Backup.Status getStatus();
|
||||
Long getSize();
|
||||
Long getProtectedSize();
|
||||
long getZoneId();
|
||||
}
|
||||
@ -0,0 +1,140 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.backup.ImportBackupOfferingCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.CreateBackupScheduleCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupOfferingsCmd;
|
||||
import org.apache.cloudstack.api.command.user.backup.ListBackupsCmd;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
||||
/**
|
||||
* Backup and Recover Manager Interface
|
||||
*/
|
||||
public interface BackupManager extends BackupService, Configurable, PluggableService, Manager {
|
||||
|
||||
ConfigKey<Boolean> BackupFrameworkEnabled = new ConfigKey<>("Advanced", Boolean.class,
|
||||
"backup.framework.enabled",
|
||||
"false",
|
||||
"Is backup and recovery framework enabled.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<String> BackupProviderPlugin = new ConfigKey<>("Advanced", String.class,
|
||||
"backup.framework.provider.plugin",
|
||||
"dummy",
|
||||
"The backup and recovery provider plugin.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<Long> BackupSyncPollingInterval = new ConfigKey<>("Advanced", Long.class,
|
||||
"backup.framework.sync.interval",
|
||||
"300",
|
||||
"The backup and recovery background sync task polling interval in seconds.", true);
|
||||
|
||||
/**
|
||||
* List backup provider offerings
|
||||
* @param zoneId zone id
|
||||
*/
|
||||
List<BackupOffering> listBackupProviderOfferings(final Long zoneId);
|
||||
|
||||
/**
|
||||
* Add a new Backup and Recovery policy to CloudStack by mapping an existing external backup offering to a name and description
|
||||
* @param cmd import backup offering cmd
|
||||
*/
|
||||
BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd);
|
||||
|
||||
/**
|
||||
* List backup offerings
|
||||
* @param ListBackupOfferingsCmd API cmd
|
||||
*/
|
||||
Pair<List<BackupOffering>, Integer> listBackupOfferings(final ListBackupOfferingsCmd cmd);
|
||||
|
||||
/**
|
||||
* Deletes a backup offering
|
||||
*/
|
||||
boolean deleteBackupOffering(final Long policyId);
|
||||
|
||||
/**
|
||||
* Assigns a VM to a backup offering
|
||||
* @param vmId
|
||||
* @param offeringId
|
||||
* @return
|
||||
*/
|
||||
boolean assignVMToBackupOffering(final Long vmId, final Long offeringId);
|
||||
|
||||
/**
|
||||
* Removes a VM from a backup offering
|
||||
* @param vmId
|
||||
* @param forced
|
||||
* @return
|
||||
*/
|
||||
boolean removeVMFromBackupOffering(final Long vmId, final boolean forced);
|
||||
|
||||
/**
|
||||
* Creates or Updates a VM backup schedule
|
||||
* @param cmd
|
||||
* @return
|
||||
*/
|
||||
BackupSchedule configureBackupSchedule(CreateBackupScheduleCmd cmd);
|
||||
|
||||
/**
|
||||
* Lists VM backup schedule for a VM
|
||||
* @param vmId
|
||||
* @return
|
||||
*/
|
||||
BackupSchedule listBackupSchedule(Long vmId);
|
||||
|
||||
/**
|
||||
* Deletes VM backup schedule for a VM
|
||||
* @param vmId
|
||||
* @return
|
||||
*/
|
||||
boolean deleteBackupSchedule(Long vmId);
|
||||
|
||||
/**
|
||||
* Creates backup of a VM
|
||||
* @param vmId Virtual Machine ID
|
||||
* @return returns operation success
|
||||
*/
|
||||
boolean createBackup(final Long vmId);
|
||||
|
||||
/**
|
||||
* List existing backups for a VM
|
||||
*/
|
||||
Pair<List<Backup>, Integer> listBackups(final ListBackupsCmd cmd);
|
||||
|
||||
/**
|
||||
* Restore a full VM from backup
|
||||
*/
|
||||
boolean restoreBackup(final Long backupId);
|
||||
|
||||
/**
|
||||
* Restore a backed up volume and attach it to a VM
|
||||
*/
|
||||
boolean restoreBackupVolumeAndAttachToVM(final String backedUpVolumeUuid, final Long backupId, final Long vmId) throws Exception;
|
||||
|
||||
/**
|
||||
* Deletes a backup
|
||||
* @return returns operation success
|
||||
*/
|
||||
boolean deleteBackup(final Long backupId);
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface BackupOffering extends InternalIdentity, Identity {
|
||||
String getExternalId();
|
||||
String getName();
|
||||
String getDescription();
|
||||
long getZoneId();
|
||||
boolean isUserDrivenBackupAllowed();
|
||||
String getProvider();
|
||||
Date getCreated();
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public interface BackupProvider {
|
||||
|
||||
/**
|
||||
* Returns the unique name of the provider
|
||||
* @return returns provider name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns description about the backup and recovery provider plugin
|
||||
* @return returns description
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Returns the list of existing backup policies on the provider
|
||||
* @return backup policies list
|
||||
*/
|
||||
List<BackupOffering> listBackupOfferings(Long zoneId);
|
||||
|
||||
/**
|
||||
* True if a backup offering exists on the backup provider
|
||||
*/
|
||||
boolean isValidProviderOffering(Long zoneId, String uuid);
|
||||
|
||||
/**
|
||||
* Assign a VM to a backup offering or policy
|
||||
* @param vm
|
||||
* @param backup
|
||||
* @param policy
|
||||
* @return
|
||||
*/
|
||||
boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backupOffering);
|
||||
|
||||
/**
|
||||
* Removes a VM from a backup offering or policy
|
||||
* @param vm
|
||||
* @return
|
||||
*/
|
||||
boolean removeVMFromBackupOffering(VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Whether the provide will delete backups on removal of VM from the offfering
|
||||
* @return boolean result
|
||||
*/
|
||||
boolean willDeleteBackupsOnOfferingRemoval();
|
||||
|
||||
/**
|
||||
* Starts and creates an adhoc backup process
|
||||
* for a previously registered VM backup
|
||||
* @param backup
|
||||
* @return
|
||||
*/
|
||||
boolean takeBackup(VirtualMachine vm);
|
||||
|
||||
/**
|
||||
* Delete an existing backup
|
||||
* @param backup
|
||||
* @return
|
||||
*/
|
||||
boolean deleteBackup(Backup backup);
|
||||
|
||||
/**
|
||||
* Restore VM from backup
|
||||
*/
|
||||
boolean restoreVMFromBackup(VirtualMachine vm, Backup backup);
|
||||
|
||||
/**
|
||||
* Restore a volume from a backup
|
||||
*/
|
||||
Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeUuid, String hostIp, String dataStoreUuid);
|
||||
|
||||
/**
|
||||
* Returns backup metrics for a list of VMs in a zone
|
||||
* @param zoneId
|
||||
* @param vms
|
||||
* @return
|
||||
*/
|
||||
Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms);
|
||||
|
||||
/**
|
||||
* This method should reconcile and create backup entries for any backups created out-of-band
|
||||
* @param vm
|
||||
* @param metric
|
||||
*/
|
||||
void syncBackups(VirtualMachine vm, Backup.Metric metric);
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import com.cloud.utils.DateUtil;
|
||||
|
||||
public interface BackupSchedule extends InternalIdentity {
|
||||
Long getVmId();
|
||||
DateUtil.IntervalType getScheduleType();
|
||||
String getSchedule();
|
||||
String getTimezone();
|
||||
Date getScheduledTimestamp();
|
||||
Long getAsyncJobId();
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Backup and Recovery Services
|
||||
*/
|
||||
public interface BackupService {
|
||||
/**
|
||||
* Lists backup and recovery provider plugins
|
||||
* @return list of providers
|
||||
*/
|
||||
List<BackupProvider> listBackupProviders();
|
||||
|
||||
/**
|
||||
* Find backup provider by zone ID
|
||||
* @param zoneId zone id
|
||||
* @return backup provider
|
||||
*/
|
||||
BackupProvider getBackupProvider(final Long zoneId);
|
||||
}
|
||||
@ -44,6 +44,7 @@ public class UsageTypes {
|
||||
public static final int VM_SNAPSHOT = 25;
|
||||
public static final int VOLUME_SECONDARY = 26;
|
||||
public static final int VM_SNAPSHOT_ON_PRIMARY = 27;
|
||||
public static final int BACKUP = 28;
|
||||
|
||||
public static List<UsageTypeResponse> listUsageTypes() {
|
||||
List<UsageTypeResponse> responseList = new ArrayList<UsageTypeResponse>();
|
||||
@ -68,6 +69,7 @@ public class UsageTypes {
|
||||
responseList.add(new UsageTypeResponse(VM_SNAPSHOT, "VM Snapshot storage usage"));
|
||||
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"));
|
||||
return responseList;
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,6 +478,11 @@
|
||||
<artifactId>cloud-plugin-integrations-prometheus-exporter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-backup-dummy</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
@ -768,6 +773,33 @@
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/spring.schemas</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/services/com.sun.tools.xjc.Plugin</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/cxf/cxf.extension</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/extensions.xml</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/cxf/extensions.xml</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
|
||||
<resource>META-INF/cxf/bus-extensions.txt</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/cxf/bus-extensions.xml</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/wsdl.plugin.xml</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/tools.service.validator.xml</resource>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
|
||||
<resource>META-INF/cxf/java2wsbeans.xml</resource>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
@ -902,6 +934,16 @@
|
||||
<artifactId>cloud-plugin-network-cisco-vnmc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-api-vmware-sioc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-backup-veeam</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
@ -919,21 +961,6 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>vmwaresioc</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>noredist</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-api-vmware-sioc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>quickcloud</id>
|
||||
<activation>
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
name=backup
|
||||
parent=backend
|
||||
@ -0,0 +1,32 @@
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
|
||||
>
|
||||
|
||||
<bean class="org.apache.cloudstack.spring.lifecycle.registry.RegistryLifecycle">
|
||||
<property name="registry" ref="backupProvidersRegistry" />
|
||||
<property name="typeClass" value="org.apache.cloudstack.backup.BackupProvider" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@ -328,4 +328,8 @@
|
||||
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
<bean id="backupProvidersRegistry"
|
||||
class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
||||
@ -121,6 +121,8 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
|
||||
|
||||
List<NetworkVO> listNetworkVO(List<Long> idset);
|
||||
|
||||
NetworkVO findByVlan(String vlan);
|
||||
|
||||
List<NetworkVO> listByAccountIdNetworkName(long accountId, String name);
|
||||
|
||||
List<NetworkVO> listByPhysicalNetworkPvlan(long physicalNetworkId, String broadcastUri, Network.PVlanType pVlanType);
|
||||
|
||||
@ -718,6 +718,14 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
|
||||
return this.search(sc_2, searchFilter_2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkVO findByVlan(String vlan) {
|
||||
SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("broadcastType", BroadcastDomainType.Vlan);
|
||||
sc.setParameters("broadcastUri", BroadcastDomainType.Vlan.toUri(vlan));
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listByAccountIdNetworkName(final long accountId, final String name) {
|
||||
final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
|
||||
|
||||
@ -51,4 +51,6 @@ public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long>
|
||||
ServiceOfferingVO getComputeOffering(ServiceOfferingVO serviceOffering, Map<String, String> customParameters);
|
||||
|
||||
ServiceOfferingVO findDefaultSystemOffering(String offeringName, Boolean useLocalStorage);
|
||||
|
||||
List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory);
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
||||
|
||||
protected final SearchBuilder<ServiceOfferingVO> UniqueNameSearch;
|
||||
protected final SearchBuilder<ServiceOfferingVO> ServiceOfferingsByKeywordSearch;
|
||||
protected final SearchBuilder<ServiceOfferingVO> PublicCpuRamSearch;
|
||||
|
||||
public ServiceOfferingDaoImpl() {
|
||||
super();
|
||||
@ -64,6 +65,12 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
||||
ServiceOfferingsByKeywordSearch.or("name", ServiceOfferingsByKeywordSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
ServiceOfferingsByKeywordSearch.or("displayText", ServiceOfferingsByKeywordSearch.entity().getDisplayText(), SearchCriteria.Op.EQ);
|
||||
ServiceOfferingsByKeywordSearch.done();
|
||||
|
||||
PublicCpuRamSearch = createSearchBuilder();
|
||||
PublicCpuRamSearch.and("cpu", PublicCpuRamSearch.entity().getCpu(), SearchCriteria.Op.EQ);
|
||||
PublicCpuRamSearch.and("ram", PublicCpuRamSearch.entity().getRamSize(), SearchCriteria.Op.EQ);
|
||||
PublicCpuRamSearch.and("system_use", PublicCpuRamSearch.entity().isSystemUse(), SearchCriteria.Op.EQ);
|
||||
PublicCpuRamSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,4 +253,13 @@ public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Lo
|
||||
}
|
||||
return serviceOffering;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceOfferingVO> listPublicByCpuAndMemory(Integer cpus, Integer memory) {
|
||||
SearchCriteria<ServiceOfferingVO> sc = PublicCpuRamSearch.create();
|
||||
sc.setParameters("cpu", cpus);
|
||||
sc.setParameters("ram", memory);
|
||||
sc.setParameters("system_use", false);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ package com.cloud.storage.dao;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface DiskOfferingDao extends GenericDao<DiskOfferingVO, Long> {
|
||||
@ -31,4 +32,6 @@ public interface DiskOfferingDao extends GenericDao<DiskOfferingVO, Long> {
|
||||
|
||||
DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering);
|
||||
|
||||
List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType);
|
||||
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@
|
||||
// under the License.
|
||||
package com.cloud.storage.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -27,12 +31,15 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.offering.DiskOffering.Type;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.utils.db.Attribute;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> implements DiskOfferingDao {
|
||||
@ -43,7 +50,11 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
||||
private final SearchBuilder<DiskOfferingVO> PrivateDiskOfferingSearch;
|
||||
private final SearchBuilder<DiskOfferingVO> PublicDiskOfferingSearch;
|
||||
protected final SearchBuilder<DiskOfferingVO> UniqueNameSearch;
|
||||
private final String SizeDiskOfferingSearch = "SELECT * FROM disk_offering WHERE " +
|
||||
"disk_size = ? AND provisioning_type = ? AND removed IS NULL";
|
||||
|
||||
private final Attribute _typeAttr;
|
||||
protected final static long GB_UNIT_BYTES = 1024 * 1024 * 1024;
|
||||
|
||||
protected DiskOfferingDaoImpl() {
|
||||
PrivateDiskOfferingSearch = createSearchBuilder();
|
||||
@ -132,6 +143,36 @@ public class DiskOfferingDaoImpl extends GenericDaoBase<DiskOfferingVO, Long> im
|
||||
}
|
||||
}
|
||||
|
||||
protected long getClosestDiskSizeInGB(long sizeInBytes) {
|
||||
if (sizeInBytes < 0) {
|
||||
throw new CloudRuntimeException("Disk size should be greater than 0 bytes, received: " + sizeInBytes + " bytes");
|
||||
}
|
||||
return (long) Math.ceil(1.0 * sizeInBytes / GB_UNIT_BYTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiskOfferingVO> listAllBySizeAndProvisioningType(long size, Storage.ProvisioningType provisioningType) {
|
||||
StringBuilder sql = new StringBuilder(SizeDiskOfferingSearch);
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
List<DiskOfferingVO> offerings = new ArrayList<>();
|
||||
try(PreparedStatement pstmt = txn.prepareStatement(sql.toString());){
|
||||
if(pstmt != null) {
|
||||
pstmt.setLong(1, size);
|
||||
pstmt.setString(2, provisioningType.toString());
|
||||
try(ResultSet rs = pstmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
offerings.add(toEntityBean(rs, false));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Exception while listing disk offerings by size: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return offerings;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Exception while listing disk offerings by size: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Long id) {
|
||||
DiskOfferingVO diskOffering = createForUpdate();
|
||||
|
||||
@ -48,4 +48,8 @@ public interface VMTemplatePoolDao extends GenericDao<VMTemplateStoragePoolVO, L
|
||||
boolean templateAvailable(long templateId, long poolId);
|
||||
|
||||
public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId);
|
||||
|
||||
VMTemplateStoragePoolVO findByPoolPath(Long poolId, String path);
|
||||
|
||||
List<VMTemplateStoragePoolVO> listByTemplatePath(String templatePath);
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplateStatesSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> TemplatePoolStateSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> updateStateSearch;
|
||||
protected final SearchBuilder<VMTemplateStoragePoolVO> templatePathSearch;
|
||||
|
||||
protected static final String UPDATE_TEMPLATE_HOST_REF = "UPDATE template_spool_ref SET download_state = ?, download_pct= ?, last_updated = ? "
|
||||
+ ", error_str = ?, local_path = ?, job_id = ? " + "WHERE pool_id = ? and template_id = ?";
|
||||
@ -114,6 +115,12 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
||||
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
|
||||
updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
|
||||
updateStateSearch.done();
|
||||
|
||||
templatePathSearch = createSearchBuilder();
|
||||
templatePathSearch.and("pool_id", templatePathSearch.entity().getPoolId(), Op.EQ);
|
||||
templatePathSearch.and("local_path", templatePathSearch.entity().getLocalDownloadPath(), Op.EQ);
|
||||
templatePathSearch.and("install_path", templatePathSearch.entity().getInstallPath(), Op.EQ);
|
||||
templatePathSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -260,6 +267,23 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase<VMTemplateStoragePoolV
|
||||
return (result.size() == 0) ? null : result.get(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMTemplateStoragePoolVO findByPoolPath(Long poolId, String path) {
|
||||
SearchCriteria<VMTemplateStoragePoolVO> sc = templatePathSearch.create();
|
||||
sc.setParameters("local_path", path);
|
||||
sc.setParameters("install_path", path);
|
||||
sc.setParameters("pool_id", poolId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMTemplateStoragePoolVO> listByTemplatePath(String templatePath) {
|
||||
SearchCriteria<VMTemplateStoragePoolVO> sc = templatePathSearch.create();
|
||||
sc.setParameters("local_path", templatePath);
|
||||
sc.setParameters("install_path", templatePath);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) {
|
||||
VMTemplateStoragePoolVO templatePool = (VMTemplateStoragePoolVO)vo;
|
||||
|
||||
@ -46,6 +46,8 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
|
||||
|
||||
List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
|
||||
|
||||
List<VolumeVO> findIncludingRemovedByInstanceAndType(long id, Volume.Type vType);
|
||||
|
||||
List<VolumeVO> findByInstanceIdAndPoolId(long instanceId, long poolId);
|
||||
|
||||
List<VolumeVO> findByInstanceIdDestroyed(long vmId);
|
||||
|
||||
@ -190,6 +190,16 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> findIncludingRemovedByInstanceAndType(long id, Type vType) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("instanceId", id);
|
||||
if (vType != null) {
|
||||
sc.setParameters("vType", vType.toString());
|
||||
}
|
||||
return listIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> findByInstanceIdDestroyed(long vmId) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
|
||||
172
engine/schema/src/main/java/com/cloud/usage/UsageBackupVO.java
Normal file
172
engine/schema/src/main/java/com/cloud/usage/UsageBackupVO.java
Normal file
@ -0,0 +1,172 @@
|
||||
// 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.usage;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
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 org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
@Entity
|
||||
@Table(name = "usage_backup")
|
||||
public class UsageBackupVO implements InternalIdentity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private long zoneId;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private long domainId;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
|
||||
@Column(name = "backup_offering_id")
|
||||
private long backupOfferingId;
|
||||
|
||||
@Column(name = "size")
|
||||
private long size;
|
||||
|
||||
@Column(name = "protected_size")
|
||||
private long protectedSize;
|
||||
|
||||
@Column(name = "created")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date created = null;
|
||||
|
||||
@Column(name = "removed")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
protected UsageBackupVO() {
|
||||
}
|
||||
|
||||
public UsageBackupVO(long zoneId, long accountId, long domainId, long vmId, long backupOfferingId, Date created) {
|
||||
this.zoneId = zoneId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.vmId = vmId;
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public UsageBackupVO(long id, long zoneId, long accountId, long domainId, long vmId, long backupOfferingId, long size, long protectedSize, Date created, Date removed) {
|
||||
this.id = id;
|
||||
this.zoneId = zoneId;
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.vmId = vmId;
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
this.size = size;
|
||||
this.protectedSize = protectedSize;
|
||||
this.created = created;
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public long getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public void setBackupOfferingId(long backupOfferingId) {
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public long getProtectedSize() {
|
||||
return protectedSize;
|
||||
}
|
||||
|
||||
public void setProtectedSize(long protectedSize) {
|
||||
this.protectedSize = protectedSize;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// 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.usage.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
import com.cloud.usage.UsageBackupVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public interface UsageBackupDao extends GenericDao<UsageBackupVO, Long> {
|
||||
void updateMetrics(VirtualMachine vm, Backup.Metric metric);
|
||||
void removeUsage(Long accountId, Long zoneId, Long backupId);
|
||||
List<UsageBackupVO> getUsageRecords(Long accountId, Date startDate, Date endDate);
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
// 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.usage.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.usage.UsageBackupVO;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
@Component
|
||||
public class UsageBackupDaoImpl extends GenericDaoBase<UsageBackupVO, Long> implements UsageBackupDao {
|
||||
public static final Logger LOGGER = Logger.getLogger(UsageBackupDaoImpl.class);
|
||||
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, zone_id, account_id, domain_id, vm_id, backup_offering_id, size, protected_size, created, removed FROM cloud_usage.usage_backup WHERE " +
|
||||
" account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " +
|
||||
" OR ((created <= ?) AND (removed >= ?)))";
|
||||
|
||||
@Override
|
||||
public void updateMetrics(final VirtualMachine vm, Backup.Metric metric) {
|
||||
boolean result = Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(final TransactionStatus status) {
|
||||
final QueryBuilder<UsageBackupVO> qb = QueryBuilder.create(UsageBackupVO.class);
|
||||
qb.and(qb.entity().getVmId(), SearchCriteria.Op.EQ, vm.getId());
|
||||
final UsageBackupVO entry = findOneBy(qb.create());
|
||||
if (entry == null) {
|
||||
return false;
|
||||
}
|
||||
entry.setSize(metric.getBackupSize());
|
||||
entry.setProtectedSize(metric.getDataSize());
|
||||
return update(entry.getId(), entry);
|
||||
}
|
||||
});
|
||||
if (!result) {
|
||||
LOGGER.trace("Failed to update backup metrics for VM ID: " + vm.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUsage(Long accountId, Long zoneId, Long vmId) {
|
||||
boolean result = Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(final TransactionStatus status) {
|
||||
final QueryBuilder<UsageBackupVO> qb = QueryBuilder.create(UsageBackupVO.class);
|
||||
qb.and(qb.entity().getAccountId(), SearchCriteria.Op.EQ, accountId);
|
||||
qb.and(qb.entity().getZoneId(), SearchCriteria.Op.EQ, zoneId);
|
||||
qb.and(qb.entity().getVmId(), SearchCriteria.Op.EQ, vmId);
|
||||
final UsageBackupVO entry = findOneBy(qb.create());
|
||||
return remove(qb.create()) > 0;
|
||||
}
|
||||
});
|
||||
if (!result) {
|
||||
LOGGER.warn("Failed to remove usage entry for backup of VM ID: " + vmId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsageBackupVO> getUsageRecords(Long accountId, Date startDate, Date endDate) {
|
||||
List<UsageBackupVO> usageRecords = new ArrayList<UsageBackupVO>();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
PreparedStatement pstmt;
|
||||
try {
|
||||
int i = 1;
|
||||
pstmt = txn.prepareAutoCloseStatement(GET_USAGE_RECORDS_BY_ACCOUNT);
|
||||
pstmt.setLong(i++, accountId);
|
||||
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate));
|
||||
pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate));
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
//id, zone_id, account_id, domain_id, vm_id, disk_offering_id, size, created, processed
|
||||
Long id = Long.valueOf(rs.getLong(1));
|
||||
Long zoneId = Long.valueOf(rs.getLong(2));
|
||||
Long acctId = Long.valueOf(rs.getLong(3));
|
||||
Long domId = Long.valueOf(rs.getLong(4));
|
||||
Long vmId = Long.valueOf(rs.getLong(5));
|
||||
Long backupOfferingId = Long.valueOf(rs.getLong(6));
|
||||
Long size = Long.valueOf(rs.getLong(7));
|
||||
Long pSize = Long.valueOf(rs.getLong(8));
|
||||
Date createdDate = null;
|
||||
Date removedDate = null;
|
||||
String createdTS = rs.getString(9);
|
||||
String removedTS = rs.getString(10);
|
||||
|
||||
if (createdTS != null) {
|
||||
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
|
||||
}
|
||||
if (removedTS != null) {
|
||||
removedDate = DateUtil.parseDateString(s_gmtTimeZone, removedTS);
|
||||
}
|
||||
usageRecords.add(new UsageBackupVO(id, zoneId, acctId, domId, vmId, backupOfferingId, size, pSize, createdDate, removedDate));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
LOGGER.warn("Error getting VM backup usage records", e);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
return usageRecords;
|
||||
}
|
||||
}
|
||||
@ -16,14 +16,14 @@
|
||||
// under the License.
|
||||
package com.cloud.vm;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import com.cloud.utils.fsm.FiniteStateObject;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
@ -39,11 +39,19 @@ import javax.persistence.TableGenerator;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import com.cloud.utils.fsm.FiniteStateObject;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@Entity
|
||||
@Table(name = "vm_instance")
|
||||
@ -186,6 +194,15 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
||||
@Column(name = "power_host", updatable = true)
|
||||
protected Long powerHostId;
|
||||
|
||||
@Column(name = "backup_offering_id")
|
||||
protected Long backupOfferingId;
|
||||
|
||||
@Column(name = "backup_external_id")
|
||||
protected String backupExternalId;
|
||||
|
||||
@Column(name = "backup_volumes")
|
||||
protected String backupVolumes;
|
||||
|
||||
public VMInstanceVO(long id, long serviceOfferingId, String name, String instanceName, Type type, Long vmTemplateId, HypervisorType hypervisorType, long guestOSId,
|
||||
long domainId, long accountId, long userId, boolean haEnabled) {
|
||||
this.id = id;
|
||||
@ -483,6 +500,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public void setRemoved(Date removed) {
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
transient String toString;
|
||||
|
||||
@Override
|
||||
@ -573,4 +594,38 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject<State, Vi
|
||||
public PartitionType partitionType() {
|
||||
return PartitionType.VM;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public void setBackupOfferingId(Long backupOfferingId) {
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBackupExternalId() {
|
||||
return backupExternalId;
|
||||
}
|
||||
|
||||
public void setBackupExternalId(String backupExternalId) {
|
||||
this.backupExternalId = backupExternalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup.VolumeInfo> getBackupVolumeList() {
|
||||
if (Strings.isNullOrEmpty(this.backupVolumes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(new Gson().fromJson(this.backupVolumes, Backup.VolumeInfo[].class));
|
||||
}
|
||||
|
||||
public void setBackupVolumes(String backupVolumes) {
|
||||
this.backupVolumes = backupVolumes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,4 +86,6 @@ public interface NicDao extends GenericDao<NicVO, Long> {
|
||||
Long getPeerRouterId(String publicMacAddress, long routerId);
|
||||
|
||||
List<NicVO> listByVmIdAndKeyword(long instanceId, String keyword);
|
||||
|
||||
NicVO findByInstanceIdAndMacAddress(long instanceId, String macAddress);
|
||||
}
|
||||
|
||||
@ -364,4 +364,12 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
|
||||
sc.setParameters("address", "%" + keyword + "%");
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicVO findByInstanceIdAndMacAddress(long instanceId, String macAddress) {
|
||||
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("instance", instanceId);
|
||||
sc.setParameters("macAddress", macAddress);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,6 +86,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
||||
|
||||
VMInstanceVO findVMByInstanceName(String name);
|
||||
|
||||
VMInstanceVO findVMByInstanceNameIncludingRemoved(String name);
|
||||
|
||||
VMInstanceVO findVMByHostName(String hostName);
|
||||
|
||||
void updateProxyId(long id, Long proxyId, Date time);
|
||||
@ -114,6 +116,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
|
||||
|
||||
List<VMInstanceVO> listVmsMigratingFromHost(Long hostId);
|
||||
|
||||
List<VMInstanceVO> listByZoneWithBackups(Long zoneId, Long backupOfferingId);
|
||||
|
||||
public Long countActiveByHostId(long hostId);
|
||||
|
||||
Pair<List<Long>, Map<Long, Double>> listClusterIdsInZoneByVmCount(long zoneId, long accountId);
|
||||
|
||||
@ -94,6 +94,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
protected SearchBuilder<VMInstanceVO> HostAndStateSearch;
|
||||
protected SearchBuilder<VMInstanceVO> StartingWithNoHostSearch;
|
||||
protected SearchBuilder<VMInstanceVO> NotMigratingSearch;
|
||||
protected SearchBuilder<VMInstanceVO> BackupSearch;
|
||||
protected SearchBuilder<VMInstanceVO> LastHostAndStatesSearch;
|
||||
|
||||
@Inject
|
||||
@ -288,6 +289,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
NotMigratingSearch.and("state", NotMigratingSearch.entity().getState(), Op.NEQ);
|
||||
NotMigratingSearch.done();
|
||||
|
||||
BackupSearch = createSearchBuilder();
|
||||
BackupSearch.and("zone_id", BackupSearch.entity().getDataCenterId(), Op.EQ);
|
||||
BackupSearch.and("backup_offering_not_null", BackupSearch.entity().getBackupOfferingId(), Op.NNULL);
|
||||
BackupSearch.and("backup_offering_id", BackupSearch.entity().getBackupOfferingId(), Op.EQ);
|
||||
BackupSearch.done();
|
||||
|
||||
LastHostAndStatesSearch = createSearchBuilder();
|
||||
LastHostAndStatesSearch.and("lastHost", LastHostAndStatesSearch.entity().getLastHostId(), Op.EQ);
|
||||
LastHostAndStatesSearch.and("states", LastHostAndStatesSearch.entity().getState(), Op.IN);
|
||||
@ -456,6 +463,13 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMInstanceVO findVMByInstanceNameIncludingRemoved(String name) {
|
||||
SearchCriteria<VMInstanceVO> sc = InstanceNameSearch.create();
|
||||
sc.setParameters("instanceName", name);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMInstanceVO findVMByHostName(String hostName) {
|
||||
SearchCriteria<VMInstanceVO> sc = HostNameSearch.create();
|
||||
@ -591,6 +605,16 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMInstanceVO> listByZoneWithBackups(Long zoneId, Long backupOfferingId) {
|
||||
SearchCriteria<VMInstanceVO> sc = BackupSearch.create();
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
if (backupOfferingId != null) {
|
||||
sc.setParameters("backup_offering_id", backupOfferingId);
|
||||
}
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countActiveByHostId(long hostId) {
|
||||
SearchCriteria<Long> sc = CountActiveByHost.create();
|
||||
|
||||
@ -0,0 +1,126 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
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;
|
||||
|
||||
@Entity
|
||||
@Table(name = "backup_offering")
|
||||
public class BackupOfferingVO implements BackupOffering {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "external_id")
|
||||
private String externalId;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private long zoneId;
|
||||
|
||||
@Column(name = "user_driven_backup")
|
||||
private boolean userDrivenBackupAllowed;
|
||||
|
||||
@Column(name = "provider")
|
||||
private String provider;
|
||||
|
||||
@Column(name = "created")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date created;
|
||||
|
||||
@Column(name = "removed")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date removed;
|
||||
|
||||
public BackupOfferingVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public BackupOfferingVO(final long zoneId, final String externalId, final String provider, final String name, final String description, final boolean userDrivenBackupAllowed) {
|
||||
this();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.zoneId = zoneId;
|
||||
this.provider = provider;
|
||||
this.externalId = externalId;
|
||||
this.userDrivenBackupAllowed = userDrivenBackupAllowed;
|
||||
this.created = new Date();
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserDrivenBackupAllowed() {
|
||||
return userDrivenBackupAllowed;
|
||||
}
|
||||
|
||||
public void setUserDrivenBackupAllowed(boolean userDrivenBackupAllowed) {
|
||||
this.userDrivenBackupAllowed = userDrivenBackupAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
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 com.cloud.utils.DateUtil;
|
||||
|
||||
@Entity
|
||||
@Table(name = "backup_schedule")
|
||||
public class BackupScheduleVO implements BackupSchedule {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private Long vmId;
|
||||
|
||||
@Column(name = "schedule_type")
|
||||
private Short scheduleType;
|
||||
|
||||
@Column(name = "schedule")
|
||||
String schedule;
|
||||
|
||||
@Column(name = "timezone")
|
||||
String timezone;
|
||||
|
||||
@Column(name = "scheduled_timestamp")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
Date scheduledTimestamp;
|
||||
|
||||
@Column(name = "async_job_id")
|
||||
Long asyncJobId;
|
||||
|
||||
public BackupScheduleVO() {
|
||||
}
|
||||
|
||||
public BackupScheduleVO(Long vmId, DateUtil.IntervalType scheduleType, String schedule, String timezone, Date scheduledTimestamp) {
|
||||
this.vmId = vmId;
|
||||
this.scheduleType = (short) scheduleType.ordinal();
|
||||
this.schedule = schedule;
|
||||
this.timezone = timezone;
|
||||
this.scheduledTimestamp = scheduledTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(Long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateUtil.IntervalType getScheduleType() {
|
||||
return scheduleType == null ? null : DateUtil.getIntervalType(scheduleType);
|
||||
}
|
||||
|
||||
public void setScheduleType(Short intervalType) {
|
||||
this.scheduleType = intervalType;
|
||||
}
|
||||
|
||||
public String getSchedule() {
|
||||
return schedule;
|
||||
}
|
||||
|
||||
public void setSchedule(String schedule) {
|
||||
this.schedule = schedule;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public Date getScheduledTimestamp() {
|
||||
return scheduledTimestamp;
|
||||
}
|
||||
|
||||
public void setScheduledTimestamp(Date scheduledTimestamp) {
|
||||
this.scheduledTimestamp = scheduledTimestamp;
|
||||
}
|
||||
|
||||
public Long getAsyncJobId() {
|
||||
return asyncJobId;
|
||||
}
|
||||
|
||||
public void setAsyncJobId(Long asyncJobId) {
|
||||
this.asyncJobId = asyncJobId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,190 @@
|
||||
//Licensed to the Apache Software Foundation (ASF) under one
|
||||
//or more contributor license agreements. See the NOTICE file
|
||||
//distributed with this work for additional information
|
||||
//regarding copyright ownership. The ASF licenses this file
|
||||
//to you under the Apache License, Version 2.0 (the
|
||||
//"License"); you may not use this file except in compliance
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing,
|
||||
//software distributed under the License is distributed on an
|
||||
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
//KIND, either express or implied. See the License for the
|
||||
//specific language governing permissions and limitations
|
||||
//under the License.
|
||||
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
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;
|
||||
|
||||
@Entity
|
||||
@Table(name = "backups")
|
||||
public class BackupVO implements Backup {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
|
||||
@Column(name = "external_id")
|
||||
private String externalId;
|
||||
|
||||
@Column(name = "type")
|
||||
private String backupType;
|
||||
|
||||
@Column(name = "date")
|
||||
private String date;
|
||||
|
||||
@Column(name = "size")
|
||||
private Long size;
|
||||
|
||||
@Column(name = "protected_size")
|
||||
private Long protectedSize;
|
||||
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private Backup.Status status;
|
||||
|
||||
@Column(name = "backup_offering_id")
|
||||
private long backupOfferingId;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private long domainId;
|
||||
|
||||
@Column(name = "zone_id")
|
||||
private long zoneId;
|
||||
|
||||
public BackupVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return backupType;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.backupType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getProtectedSize() {
|
||||
return protectedSize;
|
||||
}
|
||||
|
||||
public void setProtectedSize(Long protectedSize) {
|
||||
this.protectedSize = protectedSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public long getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
public void setBackupOfferingId(long backupOfferingId) {
|
||||
this.backupOfferingId = backupOfferingId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(long zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityType() {
|
||||
return Backup.class;
|
||||
}
|
||||
}
|
||||
@ -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.backup.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface BackupDao extends GenericDao<BackupVO, Long> {
|
||||
|
||||
Backup findByVmId(Long vmId);
|
||||
Backup findByVmIdIncludingRemoved(Long vmId);
|
||||
|
||||
List<Backup> listByVmId(Long zoneId, Long vmId);
|
||||
List<Backup> listByAccountId(Long accountId);
|
||||
List<Backup> listByOfferingId(Long offeringId);
|
||||
List<Backup> syncBackups(Long zoneId, Long vmId, List<Backup> externalBackups);
|
||||
BackupVO getBackupVO(Backup backup);
|
||||
|
||||
BackupResponse newBackupResponse(Backup backup);
|
||||
}
|
||||
@ -0,0 +1,172 @@
|
||||
// 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.backup.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.backup.BackupVO;
|
||||
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements BackupDao {
|
||||
|
||||
@Inject
|
||||
AccountDao accountDao;
|
||||
|
||||
@Inject
|
||||
DomainDao domainDao;
|
||||
|
||||
@Inject
|
||||
DataCenterDao dataCenterDao;
|
||||
|
||||
@Inject
|
||||
VMInstanceDao vmInstanceDao;
|
||||
|
||||
@Inject
|
||||
BackupOfferingDao backupOfferingDao;
|
||||
|
||||
private SearchBuilder<BackupVO> backupSearch;
|
||||
|
||||
public BackupDaoImpl() {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
backupSearch = createSearchBuilder();
|
||||
backupSearch.and("vm_id", backupSearch.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
backupSearch.and("external_id", backupSearch.entity().getExternalId(), SearchCriteria.Op.EQ);
|
||||
backupSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup> listByAccountId(Long accountId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("account_id", accountId);
|
||||
return new ArrayList<>(listBy(sc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Backup findByVmId(Long vmId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Backup findByVmIdIncludingRemoved(Long vmId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
return findOneIncludingRemovedBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup> listByVmId(Long zoneId, Long vmId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
}
|
||||
return new ArrayList<>(listBy(sc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup> listByOfferingId(Long offeringId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("offering_id", offeringId);
|
||||
return new ArrayList<>(listBy(sc));
|
||||
}
|
||||
|
||||
private Backup findByExternalId(Long zoneId, String externalId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("external_id", externalId);
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
public BackupVO getBackupVO(Backup backup) {
|
||||
BackupVO backupVO = new BackupVO();
|
||||
backupVO.setExternalId(backup.getExternalId());
|
||||
backupVO.setVmId(backup.getVmId());
|
||||
return backupVO;
|
||||
}
|
||||
|
||||
public void removeExistingBackups(Long zoneId, Long vmId) {
|
||||
SearchCriteria<BackupVO> sc = backupSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
expunge(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup> syncBackups(Long zoneId, Long vmId, List<Backup> externalBackups) {
|
||||
for (Backup backup : externalBackups) {
|
||||
BackupVO backupVO = getBackupVO(backup);
|
||||
persist(backupVO);
|
||||
}
|
||||
return listByVmId(zoneId, vmId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupResponse newBackupResponse(Backup backup) {
|
||||
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
|
||||
AccountVO account = accountDao.findByIdIncludingRemoved(vm.getAccountId());
|
||||
DomainVO domain = domainDao.findByIdIncludingRemoved(vm.getDomainId());
|
||||
DataCenterVO zone = dataCenterDao.findByIdIncludingRemoved(vm.getDataCenterId());
|
||||
BackupOffering offering = backupOfferingDao.findByIdIncludingRemoved(vm.getBackupOfferingId());
|
||||
|
||||
BackupResponse response = new BackupResponse();
|
||||
response.setId(backup.getUuid());
|
||||
response.setVmId(vm.getUuid());
|
||||
response.setVmName(vm.getHostName());
|
||||
response.setExternalId(backup.getExternalId());
|
||||
response.setType(backup.getType());
|
||||
response.setDate(backup.getDate());
|
||||
response.setSize(backup.getSize());
|
||||
response.setProtectedSize(backup.getProtectedSize());
|
||||
response.setStatus(backup.getStatus());
|
||||
response.setVolumes(new Gson().toJson(vm.getBackupVolumeList().toArray(), Backup.VolumeInfo[].class));
|
||||
response.setBackupOfferingId(offering.getUuid());
|
||||
response.setBackupOffering(offering.getName());
|
||||
response.setAccountId(account.getUuid());
|
||||
response.setAccount(account.getAccountName());
|
||||
response.setDomainId(domain.getUuid());
|
||||
response.setDomain(domain.getName());
|
||||
response.setZoneId(zone.getUuid());
|
||||
response.setZone(zone.getName());
|
||||
response.setObjectName("backup");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -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.backup.dao;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.backup.BackupOfferingVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface BackupOfferingDao extends GenericDao<BackupOfferingVO, Long> {
|
||||
BackupOfferingResponse newBackupOfferingResponse(BackupOffering policy);
|
||||
BackupOffering findByExternalId(String externalId, Long zoneId);
|
||||
BackupOffering findByName(String name, Long zoneId);
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
// 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.backup.dao;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupOfferingResponse;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.backup.BackupOfferingVO;
|
||||
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
public class BackupOfferingDaoImpl extends GenericDaoBase<BackupOfferingVO, Long> implements BackupOfferingDao {
|
||||
|
||||
@Inject
|
||||
DataCenterDao dataCenterDao;
|
||||
|
||||
private SearchBuilder<BackupOfferingVO> backupPoliciesSearch;
|
||||
|
||||
public BackupOfferingDaoImpl() {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
backupPoliciesSearch = createSearchBuilder();
|
||||
backupPoliciesSearch.and("name", backupPoliciesSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
backupPoliciesSearch.and("zone_id", backupPoliciesSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
|
||||
backupPoliciesSearch.and("external_id", backupPoliciesSearch.entity().getExternalId(), SearchCriteria.Op.EQ);
|
||||
backupPoliciesSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupOfferingResponse newBackupOfferingResponse(BackupOffering offering) {
|
||||
DataCenterVO zone = dataCenterDao.findById(offering.getZoneId());
|
||||
|
||||
BackupOfferingResponse response = new BackupOfferingResponse();
|
||||
response.setId(offering.getUuid());
|
||||
response.setName(offering.getName());
|
||||
response.setDescription(offering.getDescription());
|
||||
response.setExternalId(offering.getExternalId());
|
||||
response.setUserDrivenBackups(offering.isUserDrivenBackupAllowed());
|
||||
if (zone != null) {
|
||||
response.setZoneId(zone.getUuid());
|
||||
response.setZoneName(zone.getName());
|
||||
}
|
||||
response.setCreated(offering.getCreated());
|
||||
response.setObjectName("backupoffering");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupOffering findByExternalId(String externalId, Long zoneId) {
|
||||
SearchCriteria<BackupOfferingVO> sc = backupPoliciesSearch.create();
|
||||
sc.setParameters("external_id", externalId);
|
||||
if (zoneId != null) {
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
}
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupOffering findByName(String name, Long zoneId) {
|
||||
SearchCriteria<BackupOfferingVO> sc = backupPoliciesSearch.create();
|
||||
sc.setParameters("name", name);
|
||||
sc.setParameters("zone_id", zoneId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
// 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.backup.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.backup.BackupScheduleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface BackupScheduleDao extends GenericDao<BackupScheduleVO, Long> {
|
||||
BackupScheduleVO findByVM(Long vmId);
|
||||
|
||||
List<BackupScheduleVO> getSchedulesToExecute(Date currentTimestamp);
|
||||
|
||||
BackupScheduleResponse newBackupScheduleResponse(BackupSchedule schedule);
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
// 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.backup.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.response.BackupScheduleResponse;
|
||||
import org.apache.cloudstack.backup.BackupSchedule;
|
||||
import org.apache.cloudstack.backup.BackupScheduleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class BackupScheduleDaoImpl extends GenericDaoBase<BackupScheduleVO, Long> implements BackupScheduleDao {
|
||||
|
||||
@Inject
|
||||
VMInstanceDao vmInstanceDao;
|
||||
|
||||
private SearchBuilder<BackupScheduleVO> backupScheduleSearch;
|
||||
private SearchBuilder<BackupScheduleVO> executableSchedulesSearch;
|
||||
|
||||
public BackupScheduleDaoImpl() {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
protected void init() {
|
||||
backupScheduleSearch = createSearchBuilder();
|
||||
backupScheduleSearch.and("vm_id", backupScheduleSearch.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
backupScheduleSearch.and("async_job_id", backupScheduleSearch.entity().getAsyncJobId(), SearchCriteria.Op.EQ);
|
||||
backupScheduleSearch.done();
|
||||
|
||||
executableSchedulesSearch = createSearchBuilder();
|
||||
executableSchedulesSearch.and("scheduledTimestamp", executableSchedulesSearch.entity().getScheduledTimestamp(), SearchCriteria.Op.LT);
|
||||
executableSchedulesSearch.and("asyncJobId", executableSchedulesSearch.entity().getAsyncJobId(), SearchCriteria.Op.NULL);
|
||||
executableSchedulesSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupScheduleVO findByVM(Long vmId) {
|
||||
SearchCriteria<BackupScheduleVO> sc = backupScheduleSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BackupScheduleVO> getSchedulesToExecute(Date currentTimestamp) {
|
||||
SearchCriteria<BackupScheduleVO> sc = executableSchedulesSearch.create();
|
||||
sc.setParameters("scheduledTimestamp", currentTimestamp);
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupScheduleResponse newBackupScheduleResponse(BackupSchedule schedule) {
|
||||
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(schedule.getVmId());
|
||||
BackupScheduleResponse response = new BackupScheduleResponse();
|
||||
response.setVmId(vm.getUuid());
|
||||
response.setVmName(vm.getHostName());
|
||||
response.setIntervalType(schedule.getScheduleType());
|
||||
response.setSchedule(schedule.getSchedule());
|
||||
response.setTimezone(schedule.getTimezone());
|
||||
response.setObjectName("backupschedule");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@ -16,13 +16,12 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.engine.cloud.entity.api.db;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import com.cloud.utils.fsm.FiniteStateObject;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
@ -38,11 +37,17 @@ import javax.persistence.TableGenerator;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.StateMachine;
|
||||
import com.cloud.utils.fsm.FiniteStateObject;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@Entity
|
||||
@Table(name = "vm_instance")
|
||||
@ -175,6 +180,15 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
||||
@Column(name = "display_vm", updatable = true, nullable = false)
|
||||
protected boolean display = true;
|
||||
|
||||
@Column(name = "backup_offering_id")
|
||||
protected Long backupOfferingId;
|
||||
|
||||
@Column(name = "backup_external_id")
|
||||
private String backupExternalId;
|
||||
|
||||
@Column(name = "backup_volumes")
|
||||
private String backupVolumes;
|
||||
|
||||
@Transient
|
||||
private VMReservationVO vmReservation;
|
||||
|
||||
@ -555,4 +569,19 @@ public class VMEntityVO implements VirtualMachine, FiniteStateObject<State, Virt
|
||||
public PartitionType partitionType() {
|
||||
return PartitionType.VM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getBackupOfferingId() {
|
||||
return backupOfferingId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBackupExternalId() {
|
||||
return backupExternalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Backup.VolumeInfo> getBackupVolumeList() {
|
||||
return Arrays.asList(new Gson().fromJson(this.backupVolumes, Backup.VolumeInfo[].class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,6 +218,7 @@
|
||||
<bean id="usageVPNUserDaoImpl" class="com.cloud.usage.dao.UsageVPNUserDaoImpl" />
|
||||
<bean id="usageVolumeDaoImpl" class="com.cloud.usage.dao.UsageVolumeDaoImpl" />
|
||||
<bean id="usageVmDiskDaoImpl" class="com.cloud.usage.dao.UsageVmDiskDaoImpl" />
|
||||
<bean id="usageBackupDaoImpl" class="com.cloud.usage.dao.UsageBackupDaoImpl" />
|
||||
<bean id="userAccountDaoImpl" class="com.cloud.user.dao.UserAccountDaoImpl" />
|
||||
<bean id="userAccountJoinDaoImpl" class="com.cloud.api.query.dao.UserAccountJoinDaoImpl" />
|
||||
<bean id="userIpv6AddressDaoImpl" class="com.cloud.network.dao.UserIpv6AddressDaoImpl" />
|
||||
@ -285,6 +286,9 @@
|
||||
<bean id="outOfBandManagementDaoImpl" class="org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDaoImpl" />
|
||||
<bean id="GuestOsDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.GuestOsDetailsDaoImpl" />
|
||||
<bean id="annotationDaoImpl" class="org.apache.cloudstack.annotation.dao.AnnotationDaoImpl" />
|
||||
<bean id="backupOfferingDaoImpl" class="org.apache.cloudstack.backup.dao.BackupOfferingDaoImpl" />
|
||||
<bean id="backupScheduleDaoImpl" class="org.apache.cloudstack.backup.dao.BackupScheduleDaoImpl" />
|
||||
<bean id="backupDaoImpl" class="org.apache.cloudstack.backup.dao.BackupDaoImpl" />
|
||||
<bean id="directDownloadCertificateDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateDaoImpl" />
|
||||
<bean id="directDownloadCertificateHostMapDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMapDaoImpl" />
|
||||
<bean id="templateOVFPropertiesDaoImpl" class="com.cloud.storage.dao.TemplateOVFPropertiesDaoImpl" />
|
||||
|
||||
@ -28,6 +28,256 @@ UPDATE `cloud`.`vm_template` SET guest_os_id=99 WHERE id=1;
|
||||
-- #3659 Fix typo: the past tense of shutdown is shutdown, not shutdowned
|
||||
UPDATE `cloud`.`vm_instance` SET state='Shutdown' WHERE state='Shutdowned';
|
||||
|
||||
-- Backup and Recovery
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`backup_offering` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(40) NOT NULL UNIQUE,
|
||||
`name` varchar(255) NOT NULL COMMENT 'backup offering name',
|
||||
`description` varchar(255) NOT NULL COMMENT 'backup offering description',
|
||||
`external_id` varchar(255) DEFAULT NULL COMMENT 'external ID on provider side',
|
||||
`user_driven_backup` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'whether user can do adhoc backups and backup schedules allowed, default false',
|
||||
`zone_id` bigint(20) unsigned NOT NULL COMMENT 'zone id',
|
||||
`provider` varchar(255) NOT NULL COMMENT 'backup provider',
|
||||
`created` datetime DEFAULT NULL,
|
||||
`removed` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_backup_offering__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `backup_offering_id` bigint unsigned DEFAULT NULL COMMENT 'ID of backup offering';
|
||||
ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `backup_external_id` varchar(255) DEFAULT NULL COMMENT 'ID of external backup job or container if any';
|
||||
ALTER TABLE `cloud`.`vm_instance` ADD COLUMN `backup_volumes` text DEFAULT NULL COMMENT 'details of backedup volumes';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`backups` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(40) NOT NULL UNIQUE,
|
||||
`vm_id` bigint(20) unsigned NOT NULL,
|
||||
`external_id` varchar(255) DEFAULT NULL COMMENT 'external ID',
|
||||
`type` varchar(255) NOT NULL COMMENT 'backup type',
|
||||
`date` varchar(255) NOT NULL COMMENT 'backup date',
|
||||
`size` bigint(20) DEFAULT 0 COMMENT 'size of the backup',
|
||||
`protected_size` bigint(20) DEFAULT 0,
|
||||
`status` varchar(32) DEFAULT NULL,
|
||||
`backup_offering_id` bigint(20) unsigned NOT NULL,
|
||||
`account_id` bigint(20) unsigned NOT NULL,
|
||||
`domain_id` bigint(20) unsigned NOT NULL,
|
||||
`zone_id` bigint(20) unsigned NOT NULL,
|
||||
`removed` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_backup__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_backup__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`backup_schedule` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`vm_id` bigint(20) unsigned NOT NULL UNIQUE,
|
||||
`schedule_type` int(4) DEFAULT NULL COMMENT 'backup schedulet type e.g. hourly, daily, etc.',
|
||||
`schedule` varchar(100) DEFAULT NULL COMMENT 'schedule time of execution',
|
||||
`timezone` varchar(100) DEFAULT NULL COMMENT 'the timezone in which the schedule time is specified',
|
||||
`scheduled_timestamp` datetime DEFAULT NULL COMMENT 'Time at which the backup was scheduled for execution',
|
||||
`async_job_id` bigint(20) unsigned DEFAULT NULL COMMENT 'If this schedule is being executed, it is the id of the create aysnc_job. Before that it is null',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_backup_schedule__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_backup` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`zone_id` bigint(20) unsigned NOT NULL,
|
||||
`account_id` bigint(20) unsigned NOT NULL,
|
||||
`domain_id` bigint(20) unsigned NOT NULL,
|
||||
`vm_id` bigint(20) unsigned NOT NULL,
|
||||
`backup_offering_id` bigint(20) unsigned NOT NULL,
|
||||
`size` bigint(20) DEFAULT 0,
|
||||
`protected_size` bigint(20) DEFAULT 0,
|
||||
`created` datetime NOT NULL,
|
||||
`removed` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `i_usage_backup` (`zone_id`,`account_id`,`vm_id`,`created`)
|
||||
) ENGINE=InnoDB CHARSET=utf8;
|
||||
|
||||
DROP VIEW IF EXISTS `cloud`.`user_vm_view`;
|
||||
CREATE
|
||||
VIEW `user_vm_view` AS
|
||||
SELECT
|
||||
`vm_instance`.`id` AS `id`,
|
||||
`vm_instance`.`name` AS `name`,
|
||||
`user_vm`.`display_name` AS `display_name`,
|
||||
`user_vm`.`user_data` AS `user_data`,
|
||||
`account`.`id` AS `account_id`,
|
||||
`account`.`uuid` AS `account_uuid`,
|
||||
`account`.`account_name` AS `account_name`,
|
||||
`account`.`type` AS `account_type`,
|
||||
`domain`.`id` AS `domain_id`,
|
||||
`domain`.`uuid` AS `domain_uuid`,
|
||||
`domain`.`name` AS `domain_name`,
|
||||
`domain`.`path` AS `domain_path`,
|
||||
`projects`.`id` AS `project_id`,
|
||||
`projects`.`uuid` AS `project_uuid`,
|
||||
`projects`.`name` AS `project_name`,
|
||||
`instance_group`.`id` AS `instance_group_id`,
|
||||
`instance_group`.`uuid` AS `instance_group_uuid`,
|
||||
`instance_group`.`name` AS `instance_group_name`,
|
||||
`vm_instance`.`uuid` AS `uuid`,
|
||||
`vm_instance`.`user_id` AS `user_id`,
|
||||
`vm_instance`.`last_host_id` AS `last_host_id`,
|
||||
`vm_instance`.`vm_type` AS `type`,
|
||||
`vm_instance`.`limit_cpu_use` AS `limit_cpu_use`,
|
||||
`vm_instance`.`created` AS `created`,
|
||||
`vm_instance`.`state` AS `state`,
|
||||
`vm_instance`.`removed` AS `removed`,
|
||||
`vm_instance`.`ha_enabled` AS `ha_enabled`,
|
||||
`vm_instance`.`hypervisor_type` AS `hypervisor_type`,
|
||||
`vm_instance`.`instance_name` AS `instance_name`,
|
||||
`vm_instance`.`guest_os_id` AS `guest_os_id`,
|
||||
`vm_instance`.`display_vm` AS `display_vm`,
|
||||
`guest_os`.`uuid` AS `guest_os_uuid`,
|
||||
`vm_instance`.`pod_id` AS `pod_id`,
|
||||
`host_pod_ref`.`uuid` AS `pod_uuid`,
|
||||
`vm_instance`.`private_ip_address` AS `private_ip_address`,
|
||||
`vm_instance`.`private_mac_address` AS `private_mac_address`,
|
||||
`vm_instance`.`vm_type` AS `vm_type`,
|
||||
`data_center`.`id` AS `data_center_id`,
|
||||
`data_center`.`uuid` AS `data_center_uuid`,
|
||||
`data_center`.`name` AS `data_center_name`,
|
||||
`data_center`.`is_security_group_enabled` AS `security_group_enabled`,
|
||||
`data_center`.`networktype` AS `data_center_type`,
|
||||
`host`.`id` AS `host_id`,
|
||||
`host`.`uuid` AS `host_uuid`,
|
||||
`host`.`name` AS `host_name`,
|
||||
`vm_template`.`id` AS `template_id`,
|
||||
`vm_template`.`uuid` AS `template_uuid`,
|
||||
`vm_template`.`name` AS `template_name`,
|
||||
`vm_template`.`display_text` AS `template_display_text`,
|
||||
`vm_template`.`enable_password` AS `password_enabled`,
|
||||
`iso`.`id` AS `iso_id`,
|
||||
`iso`.`uuid` AS `iso_uuid`,
|
||||
`iso`.`name` AS `iso_name`,
|
||||
`iso`.`display_text` AS `iso_display_text`,
|
||||
`service_offering`.`id` AS `service_offering_id`,
|
||||
`svc_disk_offering`.`uuid` AS `service_offering_uuid`,
|
||||
`disk_offering`.`uuid` AS `disk_offering_uuid`,
|
||||
`disk_offering`.`id` AS `disk_offering_id`,
|
||||
(CASE
|
||||
WHEN ISNULL(`service_offering`.`cpu`) THEN `custom_cpu`.`value`
|
||||
ELSE `service_offering`.`cpu`
|
||||
END) AS `cpu`,
|
||||
(CASE
|
||||
WHEN ISNULL(`service_offering`.`speed`) THEN `custom_speed`.`value`
|
||||
ELSE `service_offering`.`speed`
|
||||
END) AS `speed`,
|
||||
(CASE
|
||||
WHEN ISNULL(`service_offering`.`ram_size`) THEN `custom_ram_size`.`value`
|
||||
ELSE `service_offering`.`ram_size`
|
||||
END) AS `ram_size`,
|
||||
`backup_offering`.`uuid` AS `backup_offering_uuid`,
|
||||
`backup_offering`.`id` AS `backup_offering_id`,
|
||||
`svc_disk_offering`.`name` AS `service_offering_name`,
|
||||
`disk_offering`.`name` AS `disk_offering_name`,
|
||||
`backup_offering`.`name` AS `backup_offering_name`,
|
||||
`storage_pool`.`id` AS `pool_id`,
|
||||
`storage_pool`.`uuid` AS `pool_uuid`,
|
||||
`storage_pool`.`pool_type` AS `pool_type`,
|
||||
`volumes`.`id` AS `volume_id`,
|
||||
`volumes`.`uuid` AS `volume_uuid`,
|
||||
`volumes`.`device_id` AS `volume_device_id`,
|
||||
`volumes`.`volume_type` AS `volume_type`,
|
||||
`security_group`.`id` AS `security_group_id`,
|
||||
`security_group`.`uuid` AS `security_group_uuid`,
|
||||
`security_group`.`name` AS `security_group_name`,
|
||||
`security_group`.`description` AS `security_group_description`,
|
||||
`nics`.`id` AS `nic_id`,
|
||||
`nics`.`uuid` AS `nic_uuid`,
|
||||
`nics`.`network_id` AS `network_id`,
|
||||
`nics`.`ip4_address` AS `ip_address`,
|
||||
`nics`.`ip6_address` AS `ip6_address`,
|
||||
`nics`.`ip6_gateway` AS `ip6_gateway`,
|
||||
`nics`.`ip6_cidr` AS `ip6_cidr`,
|
||||
`nics`.`default_nic` AS `is_default_nic`,
|
||||
`nics`.`gateway` AS `gateway`,
|
||||
`nics`.`netmask` AS `netmask`,
|
||||
`nics`.`mac_address` AS `mac_address`,
|
||||
`nics`.`broadcast_uri` AS `broadcast_uri`,
|
||||
`nics`.`isolation_uri` AS `isolation_uri`,
|
||||
`vpc`.`id` AS `vpc_id`,
|
||||
`vpc`.`uuid` AS `vpc_uuid`,
|
||||
`networks`.`uuid` AS `network_uuid`,
|
||||
`networks`.`name` AS `network_name`,
|
||||
`networks`.`traffic_type` AS `traffic_type`,
|
||||
`networks`.`guest_type` AS `guest_type`,
|
||||
`user_ip_address`.`id` AS `public_ip_id`,
|
||||
`user_ip_address`.`uuid` AS `public_ip_uuid`,
|
||||
`user_ip_address`.`public_ip_address` AS `public_ip_address`,
|
||||
`ssh_keypairs`.`keypair_name` AS `keypair_name`,
|
||||
`resource_tags`.`id` AS `tag_id`,
|
||||
`resource_tags`.`uuid` AS `tag_uuid`,
|
||||
`resource_tags`.`key` AS `tag_key`,
|
||||
`resource_tags`.`value` AS `tag_value`,
|
||||
`resource_tags`.`domain_id` AS `tag_domain_id`,
|
||||
`domain`.`uuid` AS `tag_domain_uuid`,
|
||||
`domain`.`name` AS `tag_domain_name`,
|
||||
`resource_tags`.`account_id` AS `tag_account_id`,
|
||||
`account`.`account_name` AS `tag_account_name`,
|
||||
`resource_tags`.`resource_id` AS `tag_resource_id`,
|
||||
`resource_tags`.`resource_uuid` AS `tag_resource_uuid`,
|
||||
`resource_tags`.`resource_type` AS `tag_resource_type`,
|
||||
`resource_tags`.`customer` AS `tag_customer`,
|
||||
`async_job`.`id` AS `job_id`,
|
||||
`async_job`.`uuid` AS `job_uuid`,
|
||||
`async_job`.`job_status` AS `job_status`,
|
||||
`async_job`.`account_id` AS `job_account_id`,
|
||||
`affinity_group`.`id` AS `affinity_group_id`,
|
||||
`affinity_group`.`uuid` AS `affinity_group_uuid`,
|
||||
`affinity_group`.`name` AS `affinity_group_name`,
|
||||
`affinity_group`.`description` AS `affinity_group_description`,
|
||||
`vm_instance`.`dynamically_scalable` AS `dynamically_scalable`
|
||||
FROM
|
||||
(((((((((((((((((((((((((((((((((`user_vm`
|
||||
JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`)
|
||||
AND ISNULL(`vm_instance`.`removed`))))
|
||||
JOIN `account` ON ((`vm_instance`.`account_id` = `account`.`id`)))
|
||||
JOIN `domain` ON ((`vm_instance`.`domain_id` = `domain`.`id`)))
|
||||
LEFT JOIN `guest_os` ON ((`vm_instance`.`guest_os_id` = `guest_os`.`id`)))
|
||||
LEFT JOIN `host_pod_ref` ON ((`vm_instance`.`pod_id` = `host_pod_ref`.`id`)))
|
||||
LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`)))
|
||||
LEFT JOIN `instance_group_vm_map` ON ((`vm_instance`.`id` = `instance_group_vm_map`.`instance_id`)))
|
||||
LEFT JOIN `instance_group` ON ((`instance_group_vm_map`.`group_id` = `instance_group`.`id`)))
|
||||
LEFT JOIN `data_center` ON ((`vm_instance`.`data_center_id` = `data_center`.`id`)))
|
||||
LEFT JOIN `host` ON ((`vm_instance`.`host_id` = `host`.`id`)))
|
||||
LEFT JOIN `vm_template` ON ((`vm_instance`.`vm_template_id` = `vm_template`.`id`)))
|
||||
LEFT JOIN `vm_template` `iso` ON ((`iso`.`id` = `user_vm`.`iso_id`)))
|
||||
LEFT JOIN `service_offering` ON ((`vm_instance`.`service_offering_id` = `service_offering`.`id`)))
|
||||
LEFT JOIN `disk_offering` `svc_disk_offering` ON ((`vm_instance`.`service_offering_id` = `svc_disk_offering`.`id`)))
|
||||
LEFT JOIN `disk_offering` ON ((`vm_instance`.`disk_offering_id` = `disk_offering`.`id`)))
|
||||
LEFT JOIN `backup_offering` ON ((`vm_instance`.`backup_offering_id` = `backup_offering`.`id`)))
|
||||
LEFT JOIN `volumes` ON ((`vm_instance`.`id` = `volumes`.`instance_id`)))
|
||||
LEFT JOIN `storage_pool` ON ((`volumes`.`pool_id` = `storage_pool`.`id`)))
|
||||
LEFT JOIN `security_group_vm_map` ON ((`vm_instance`.`id` = `security_group_vm_map`.`instance_id`)))
|
||||
LEFT JOIN `security_group` ON ((`security_group_vm_map`.`security_group_id` = `security_group`.`id`)))
|
||||
LEFT JOIN `nics` ON (((`vm_instance`.`id` = `nics`.`instance_id`)
|
||||
AND ISNULL(`nics`.`removed`))))
|
||||
LEFT JOIN `networks` ON ((`nics`.`network_id` = `networks`.`id`)))
|
||||
LEFT JOIN `vpc` ON (((`networks`.`vpc_id` = `vpc`.`id`)
|
||||
AND ISNULL(`vpc`.`removed`))))
|
||||
LEFT JOIN `user_ip_address` ON ((`user_ip_address`.`vm_id` = `vm_instance`.`id`)))
|
||||
LEFT JOIN `user_vm_details` `ssh_details` ON (((`ssh_details`.`vm_id` = `vm_instance`.`id`)
|
||||
AND (`ssh_details`.`name` = 'SSH.PublicKey'))))
|
||||
LEFT JOIN `ssh_keypairs` ON (((`ssh_keypairs`.`public_key` = `ssh_details`.`value`)
|
||||
AND (`ssh_keypairs`.`account_id` = `account`.`id`))))
|
||||
LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_instance`.`id`)
|
||||
AND (`resource_tags`.`resource_type` = 'UserVm'))))
|
||||
LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `vm_instance`.`id`)
|
||||
AND (`async_job`.`instance_type` = 'VirtualMachine')
|
||||
AND (`async_job`.`job_status` = 0))))
|
||||
LEFT JOIN `affinity_group_vm_map` ON ((`vm_instance`.`id` = `affinity_group_vm_map`.`instance_id`)))
|
||||
LEFT JOIN `affinity_group` ON ((`affinity_group_vm_map`.`affinity_group_id` = `affinity_group`.`id`)))
|
||||
LEFT JOIN `user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `vm_instance`.`id`)
|
||||
AND (`custom_cpu`.`name` = 'CpuNumber'))))
|
||||
LEFT JOIN `user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `vm_instance`.`id`)
|
||||
AND (`custom_speed`.`name` = 'CpuSpeed'))))
|
||||
LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`)
|
||||
AND (`custom_ram_size`.`name` = 'memory'))));
|
||||
|
||||
-- Fix OS category for some Ubuntu and RedHat OS-es
|
||||
UPDATE `cloud`.`guest_os` SET `category_id`='10' WHERE `id`=277 AND display_name="Ubuntu 17.04";
|
||||
UPDATE `cloud`.`guest_os` SET `category_id`='10' WHERE `id`=278 AND display_name="Ubuntu 17.10";
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
// 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.utils.exception.CloudRuntimeException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DiskOfferingDaoImplTest {
|
||||
|
||||
private final DiskOfferingDaoImpl dao = new DiskOfferingDaoImpl();
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void testGetClosestDiskSizeInGBNegativeSize() {
|
||||
long size = -4 * DiskOfferingDaoImpl.GB_UNIT_BYTES;
|
||||
dao.getClosestDiskSizeInGB(size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClosestDiskSizeInGBSizeGB() {
|
||||
int gbUnits = 5;
|
||||
long size = gbUnits * DiskOfferingDaoImpl.GB_UNIT_BYTES;
|
||||
long sizeInGB = dao.getClosestDiskSizeInGB(size);
|
||||
Assert.assertEquals(gbUnits, sizeInGB);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClosestDiskSizeInGBSizeGBRest() {
|
||||
int gbUnits = 5;
|
||||
long size = gbUnits * DiskOfferingDaoImpl.GB_UNIT_BYTES + 12345;
|
||||
long sizeInGB = dao.getClosestDiskSizeInGB(size);
|
||||
Assert.assertEquals(gbUnits + 1, sizeInGB);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClosestDiskSizeInGBSizeLessOneGB() {
|
||||
int gbUnits = 1;
|
||||
long size = gbUnits * DiskOfferingDaoImpl.GB_UNIT_BYTES - 12345;
|
||||
long sizeInGB = dao.getClosestDiskSizeInGB(size);
|
||||
Assert.assertEquals(gbUnits, sizeInGB);
|
||||
}
|
||||
}
|
||||
@ -234,6 +234,8 @@ public interface GenericDao<T, ID extends Serializable> {
|
||||
*/
|
||||
void expunge();
|
||||
|
||||
boolean unremove(ID id);
|
||||
|
||||
public <K> K getNextInSequence(Class<K> clazz, String name);
|
||||
|
||||
/**
|
||||
|
||||
@ -1785,6 +1785,34 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unremove(ID id) {
|
||||
if (_removed == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
txn.start();
|
||||
pstmt = txn.prepareAutoCloseStatement(_removeSql.first());
|
||||
final Attribute[] attrs = _removeSql.second();
|
||||
pstmt.setObject(1, null);
|
||||
for (int i = 0; i < attrs.length - 1; i++) {
|
||||
prepareAttribute(i + 2, pstmt, attrs[i], id);
|
||||
}
|
||||
|
||||
final int result = pstmt.executeUpdate();
|
||||
txn.commit();
|
||||
if (_cache != null) {
|
||||
_cache.remove(id);
|
||||
}
|
||||
return result > 0;
|
||||
} catch (final SQLException e) {
|
||||
throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
|
||||
}
|
||||
}
|
||||
|
||||
@DB()
|
||||
protected void setField(final Object entity, final ResultSet rs, ResultSetMetaData meta, final int index) throws SQLException {
|
||||
Attribute attr = _allColumns.get(new Pair<String, String>(meta.getTableName(index), meta.getColumnName(index)));
|
||||
|
||||
@ -158,6 +158,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
case QuotaTypes.ISO:
|
||||
case QuotaTypes.VOLUME:
|
||||
case QuotaTypes.VM_SNAPSHOT:
|
||||
case QuotaTypes.BACKUP:
|
||||
qu = updateQuotaDiskUsage(usageRecord, aggregationRatio, usageRecord.getUsageType());
|
||||
if (qu != null) {
|
||||
quotaListForAccount.add(qu);
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.quota.constant;
|
||||
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
|
||||
public class QuotaTypes extends UsageTypes {
|
||||
public static final int CPU_CLOCK_RATE = 15;
|
||||
public static final int CPU_NUMBER = 16;
|
||||
@ -57,6 +57,7 @@ public class QuotaTypes extends UsageTypes {
|
||||
quotaTypeList.put(VM_SNAPSHOT, new QuotaTypes(VM_SNAPSHOT, "VM_SNAPSHOT", "GB-Month", "VM Snapshot storage usage"));
|
||||
quotaTypeList.put(VOLUME_SECONDARY, new QuotaTypes(VOLUME_SECONDARY, "VOLUME_SECONDARY", "GB-Month", "Volume secondary storage usage"));
|
||||
quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", "GB-Month", "VM Snapshot primary storage usage"));
|
||||
quotaTypeList.put(BACKUP, new QuotaTypes(BACKUP, "BACKUP", "GB-Month", "Backup storage usage"));
|
||||
quotaTypeList.put(CPU_CLOCK_RATE, new QuotaTypes(CPU_CLOCK_RATE, "CPU_CLOCK_RATE", "Compute-Month", "Quota tariff for using 1 CPU of clock rate 100MHz"));
|
||||
quotaTypeList.put(CPU_NUMBER, new QuotaTypes(CPU_NUMBER, "CPU_NUMBER", "Compute-Month", "Quota tariff for running VM that has 1vCPU"));
|
||||
quotaTypeList.put(MEMORY, new QuotaTypes(MEMORY, "MEMORY", "Compute-Month", "Quota tariff for using 1MB of RAM"));
|
||||
|
||||
41
plugins/backup/dummy/pom.xml
Normal file
41
plugins/backup/dummy/pom.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-plugin-backup-dummy</artifactId>
|
||||
<name>Apache CloudStack Plugin - Dummy Backup and Recovery Plugin</name>
|
||||
<parent>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<version>4.14.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,134 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.backup.dao.BackupDao;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class DummyBackupProvider extends AdapterBase implements BackupProvider {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(DummyBackupProvider.class);
|
||||
|
||||
@Inject
|
||||
private BackupDao backupDao;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "dummy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Dummy Backup Plugin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BackupOffering> listBackupOfferings(Long zoneId) {
|
||||
s_logger.debug("Listing backup policies on Dummy B&R Plugin");
|
||||
BackupOffering policy1 = new BackupOfferingVO(1, "gold-policy", "dummy", "Golden Policy", "Gold description", true);
|
||||
BackupOffering policy2 = new BackupOfferingVO(1, "silver-policy", "dummy", "Silver Policy", "Silver description", true);
|
||||
return Arrays.asList(policy1, policy2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProviderOffering(Long zoneId, String uuid) {
|
||||
s_logger.debug("Checking if backup offering exists on the Dummy Backup Provider");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backupOffering) {
|
||||
s_logger.debug("Creating VM backup for VM " + vm.getInstanceName() + " from backup offering " + backupOffering.getName());
|
||||
((VMInstanceVO) vm).setBackupExternalId("dummy-external-backup-id");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
|
||||
s_logger.debug("Restoring vm " + vm.getUuid() + "from backup " + backup.getUuid() + " on the Dummy Backup Provider");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeUuid, String hostIp, String dataStoreUuid) {
|
||||
s_logger.debug("Restoring volume " + volumeUuid + "from backup " + backup.getUuid() + " on the Dummy Backup Provider");
|
||||
throw new CloudRuntimeException("Dummy plugin does not support this feature");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
|
||||
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
||||
final Backup.Metric metric = new Backup.Metric(1000L, 100L);
|
||||
for (VirtualMachine vm : vms) {
|
||||
metrics.put(vm, metric);
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVMFromBackupOffering(VirtualMachine vm) {
|
||||
s_logger.debug("Removing VM ID " + vm.getUuid() + " from backup offering by the Dummy Backup Provider");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDeleteBackupsOnOfferingRemoval() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBackup(VirtualMachine vm) {
|
||||
s_logger.debug("Starting backup for VM ID " + vm.getUuid() + " on Dummy provider");
|
||||
|
||||
BackupVO backup = new BackupVO();
|
||||
backup.setVmId(vm.getId());
|
||||
backup.setExternalId("dummy-external-id");
|
||||
backup.setType("FULL");
|
||||
backup.setDate(new Date().toString());
|
||||
backup.setSize(1024L);
|
||||
backup.setProtectedSize(1024000L);
|
||||
backup.setStatus(Backup.Status.BackedUp);
|
||||
backup.setBackupOfferingId(vm.getBackupOfferingId());
|
||||
backup.setAccountId(vm.getAccountId());
|
||||
backup.setDomainId(vm.getDomainId());
|
||||
backup.setZoneId(vm.getDataCenterId());
|
||||
return backupDao.persist(backup) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteBackup(Backup backup) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncBackups(VirtualMachine vm, Backup.Metric metric) {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
# 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.
|
||||
name=dummy-backup
|
||||
parent=backup
|
||||
@ -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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
|
||||
>
|
||||
<bean id="dummyBackupRecoveryDriver" class="org.apache.cloudstack.backup.DummyBackupProvider">
|
||||
<property name="name" value="dummy" />
|
||||
</bean>
|
||||
</beans>
|
||||
54
plugins/backup/veeam/pom.xml
Normal file
54
plugins/backup/veeam/pom.xml
Normal 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-plugin-backup-veeam</artifactId>
|
||||
<name>Apache CloudStack Plugin - Veeam Backup and Recovery Plugin</name>
|
||||
<parent>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<version>4.14.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-hypervisor-vmware</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>${cs.jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${cs.commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-standalone</artifactId>
|
||||
<version>${cs.wiremock.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,310 @@
|
||||
// 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.backup;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.backup.dao.BackupDao;
|
||||
import org.apache.cloudstack.backup.veeam.VeeamClient;
|
||||
import org.apache.cloudstack.backup.veeam.api.Job;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenter;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class VeeamBackupProvider extends AdapterBase implements BackupProvider, Configurable {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(VeeamBackupProvider.class);
|
||||
public static final String BACKUP_IDENTIFIER = "-CSBKP-";
|
||||
|
||||
public ConfigKey<String> VeeamUrl = new ConfigKey<>("Advanced", String.class,
|
||||
"backup.plugin.veeam.url", "https://localhost:9398/api/",
|
||||
"The Veeam backup and recovery URL.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
private ConfigKey<String> VeeamUsername = new ConfigKey<>("Advanced", String.class,
|
||||
"backup.plugin.veeam.username", "administrator",
|
||||
"The Veeam backup and recovery username.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
private ConfigKey<String> VeeamPassword = new ConfigKey<>("Secure", String.class,
|
||||
"backup.plugin.veeam.password", "",
|
||||
"The Veeam backup and recovery password.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
private ConfigKey<Boolean> VeeamValidateSSLSecurity = new ConfigKey<>("Advanced", Boolean.class, "backup.plugin.veeam.validate.ssl", "false",
|
||||
"When set to true, this will validate the SSL certificate when connecting to https/ssl enabled Veeam API service.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
private ConfigKey<Integer> VeeamApiRequestTimeout = new ConfigKey<>("Advanced", Integer.class, "backup.plugin.veeam.request.timeout", "300",
|
||||
"The Veeam B&R API request timeout in seconds.", true, ConfigKey.Scope.Zone);
|
||||
|
||||
@Inject
|
||||
private VmwareDatacenterZoneMapDao vmwareDatacenterZoneMapDao;
|
||||
@Inject
|
||||
private VmwareDatacenterDao vmwareDatacenterDao;
|
||||
@Inject
|
||||
private BackupDao backupDao;
|
||||
|
||||
private VeeamClient getClient(final Long zoneId) {
|
||||
try {
|
||||
return new VeeamClient(VeeamUrl.valueIn(zoneId), VeeamUsername.valueIn(zoneId), VeeamPassword.valueIn(zoneId),
|
||||
VeeamValidateSSLSecurity.valueIn(zoneId), VeeamApiRequestTimeout.valueIn(zoneId));
|
||||
} catch (URISyntaxException e) {
|
||||
throw new CloudRuntimeException("Failed to parse Veeam API URL: " + e.getMessage());
|
||||
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
||||
LOG.error("Failed to build Veeam API client due to: ", e);
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to build Veeam API client");
|
||||
}
|
||||
|
||||
public List<BackupOffering> listBackupOfferings(final Long zoneId) {
|
||||
List<BackupOffering> policies = new ArrayList<>();
|
||||
for (final BackupOffering policy : getClient(zoneId).listJobs()) {
|
||||
if (!policy.getName().contains(BACKUP_IDENTIFIER)) {
|
||||
policies.add(policy);
|
||||
}
|
||||
}
|
||||
return policies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidProviderOffering(final Long zoneId, final String uuid) {
|
||||
List<BackupOffering> policies = listBackupOfferings(zoneId);
|
||||
if (CollectionUtils.isEmpty(policies)) {
|
||||
return false;
|
||||
}
|
||||
for (final BackupOffering policy : policies) {
|
||||
if (policy.getExternalId().equals(uuid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private VmwareDatacenter findVmwareDatacenterForVM(final VirtualMachine vm) {
|
||||
if (vm == null || vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
|
||||
throw new CloudRuntimeException("The Veeam backup provider is only applicable for VMware VMs");
|
||||
}
|
||||
final VmwareDatacenterZoneMap zoneMap = vmwareDatacenterZoneMapDao.findByZoneId(vm.getDataCenterId());
|
||||
if (zoneMap == null) {
|
||||
throw new CloudRuntimeException("Failed to find a mapped VMware datacenter for zone id:" + vm.getDataCenterId());
|
||||
}
|
||||
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterDao.findById(zoneMap.getVmwareDcId());
|
||||
if (vmwareDatacenter == null) {
|
||||
throw new CloudRuntimeException("Failed to find a valid VMware datacenter mapped for zone id:" + vm.getDataCenterId());
|
||||
}
|
||||
return vmwareDatacenter;
|
||||
}
|
||||
|
||||
private String getGuestBackupName(final String instanceName, final String uuid) {
|
||||
return String.format("%s%s%s", instanceName, BACKUP_IDENTIFIER, uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean assignVMToBackupOffering(final VirtualMachine vm, final BackupOffering backupOffering) {
|
||||
final VeeamClient client = getClient(vm.getDataCenterId());
|
||||
final Job parentJob = client.listJob(backupOffering.getExternalId());
|
||||
final String clonedJobName = getGuestBackupName(vm.getInstanceName(), vm.getUuid());
|
||||
|
||||
if (!client.cloneVeeamJob(parentJob, clonedJobName)) {
|
||||
LOG.error("Failed to clone pre-defined Veeam job (backup offering) for backup offering ID: " + backupOffering.getExternalId() + " but will check the list of jobs again if it was eventually succeeded.");
|
||||
}
|
||||
|
||||
for (final BackupOffering job : client.listJobs()) {
|
||||
if (job.getName().equals(clonedJobName)) {
|
||||
final Job clonedJob = client.listJob(job.getExternalId());
|
||||
if (clonedJob.getScheduleConfigured() && !clonedJob.getScheduleEnabled()) {
|
||||
client.toggleJobSchedule(clonedJob.getId());
|
||||
}
|
||||
LOG.debug("Veeam job (backup offering) for backup offering ID: " + backupOffering.getExternalId() + " found, now trying to assign the VM to the job.");
|
||||
final VmwareDatacenter vmwareDC = findVmwareDatacenterForVM(vm);
|
||||
if (client.addVMToVeeamJob(job.getExternalId(), vm.getInstanceName(), vmwareDC.getVcenterHost())) {
|
||||
((VMInstanceVO) vm).setBackupExternalId(job.getExternalId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVMFromBackupOffering(final VirtualMachine vm) {
|
||||
final VeeamClient client = getClient(vm.getDataCenterId());
|
||||
final VmwareDatacenter vmwareDC = findVmwareDatacenterForVM(vm);
|
||||
try {
|
||||
if (!client.removeVMFromVeeamJob(vm.getBackupExternalId(), vm.getInstanceName(), vmwareDC.getVcenterHost())) {
|
||||
LOG.warn("Failed to remove VM from Veeam Job id: " + vm.getBackupExternalId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("VM was removed from the job so could not remove again, trying to delete the veeam job now.", e);
|
||||
}
|
||||
|
||||
final String clonedJobName = getGuestBackupName(vm.getInstanceName(), vm.getUuid());
|
||||
if (!client.deleteJobAndBackup(clonedJobName)) {
|
||||
LOG.warn("Failed to remove Veeam job and backup for job: " + clonedJobName);
|
||||
throw new CloudRuntimeException("Failed to delete Veeam B&R job and backup, an operation may be in progress. Please try again after some time.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDeleteBackupsOnOfferingRemoval() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takeBackup(final VirtualMachine vm) {
|
||||
final VeeamClient client = getClient(vm.getDataCenterId());
|
||||
return client.startBackupJob(vm.getBackupExternalId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteBackup(Backup backup) {
|
||||
// Veeam does not support removal of a restore point or point-in-time backup
|
||||
throw new CloudRuntimeException("Veeam B&R plugin does not allow removal of backup restore point, to delete the backup chain remove VM from the backup offering");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
|
||||
final String restorePointId = backup.getExternalId();
|
||||
return getClient(vm.getDataCenterId()).restoreFullVM(vm.getInstanceName(), restorePointId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeUuid, String hostIp, String dataStoreUuid) {
|
||||
final Long zoneId = backup.getZoneId();
|
||||
final String restorePointId = backup.getExternalId();
|
||||
return getClient(zoneId).restoreVMToDifferentLocation(restorePointId, hostIp, dataStoreUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(final Long zoneId, final List<VirtualMachine> vms) {
|
||||
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
|
||||
final Map<String, Backup.Metric> backendMetrics = getClient(zoneId).getBackupMetrics();
|
||||
for (final VirtualMachine vm : vms) {
|
||||
if (!backendMetrics.containsKey(vm.getUuid())) {
|
||||
continue;
|
||||
}
|
||||
metrics.put(vm, backendMetrics.get(vm.getUuid()));
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm) {
|
||||
String backupName = getGuestBackupName(vm.getInstanceName(), vm.getUuid());
|
||||
return getClient(vm.getDataCenterId()).listRestorePoints(backupName, vm.getInstanceName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncBackups(VirtualMachine vm, Backup.Metric metric) {
|
||||
List<Backup.RestorePoint> restorePoints = listRestorePoints(vm);
|
||||
if (restorePoints == null || restorePoints.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
final List<Backup> backupsInDb = backupDao.listByVmId(null, vm.getId());
|
||||
final List<Long> removeList = backupsInDb.stream().map(InternalIdentity::getId).collect(Collectors.toList());
|
||||
for (final Backup.RestorePoint restorePoint : restorePoints) {
|
||||
boolean backupExists = false;
|
||||
for (final Backup backup : backupsInDb) {
|
||||
if (restorePoint.getId().equals(backup.getExternalId())) {
|
||||
backupExists = true;
|
||||
removeList.remove(backup.getId());
|
||||
if (metric != null) {
|
||||
((BackupVO) backup).setSize(metric.getBackupSize());
|
||||
((BackupVO) backup).setProtectedSize(metric.getDataSize());
|
||||
backupDao.update(backup.getId(), ((BackupVO) backup));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (backupExists) {
|
||||
continue;
|
||||
}
|
||||
BackupVO backup = new BackupVO();
|
||||
backup.setVmId(vm.getId());
|
||||
backup.setExternalId(restorePoint.getId());
|
||||
backup.setType(restorePoint.getType());
|
||||
backup.setDate(restorePoint.getCreated());
|
||||
backup.setStatus(Backup.Status.BackedUp);
|
||||
if (metric != null) {
|
||||
backup.setSize(metric.getBackupSize());
|
||||
backup.setProtectedSize(metric.getDataSize());
|
||||
}
|
||||
backup.setBackupOfferingId(vm.getBackupOfferingId());
|
||||
backup.setAccountId(vm.getAccountId());
|
||||
backup.setDomainId(vm.getDomainId());
|
||||
backup.setZoneId(vm.getDataCenterId());
|
||||
backupDao.persist(backup);
|
||||
}
|
||||
for (final Long backupIdToRemove : removeList) {
|
||||
backupDao.remove(backupIdToRemove);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return BackupService.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey[]{
|
||||
VeeamUrl,
|
||||
VeeamUsername,
|
||||
VeeamPassword,
|
||||
VeeamValidateSSLSecurity,
|
||||
VeeamApiRequestTimeout
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "veeam";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Veeam Backup Plugin";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
// 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.backup.veeam;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
|
||||
public class VeeamBackupOffering implements BackupOffering {
|
||||
|
||||
private String name;
|
||||
private String uid;
|
||||
|
||||
public VeeamBackupOffering(String name, String uid) {
|
||||
this.name = name;
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExternalId() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Veeam Backup Offering (Job)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getZoneId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserDrivenBackupAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvider() {
|
||||
return "veeam";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreated() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,654 @@
|
||||
// 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.backup.veeam;
|
||||
|
||||
import static org.apache.cloudstack.backup.VeeamBackupProvider.BACKUP_IDENTIFIER;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.backup.veeam.api.BackupJobCloneInfo;
|
||||
import org.apache.cloudstack.backup.veeam.api.CreateObjectInJobSpec;
|
||||
import org.apache.cloudstack.backup.veeam.api.EntityReferences;
|
||||
import org.apache.cloudstack.backup.veeam.api.HierarchyItem;
|
||||
import org.apache.cloudstack.backup.veeam.api.HierarchyItems;
|
||||
import org.apache.cloudstack.backup.veeam.api.Job;
|
||||
import org.apache.cloudstack.backup.veeam.api.JobCloneSpec;
|
||||
import org.apache.cloudstack.backup.veeam.api.Link;
|
||||
import org.apache.cloudstack.backup.veeam.api.ObjectInJob;
|
||||
import org.apache.cloudstack.backup.veeam.api.ObjectsInJob;
|
||||
import org.apache.cloudstack.backup.veeam.api.Ref;
|
||||
import org.apache.cloudstack.backup.veeam.api.RestoreSession;
|
||||
import org.apache.cloudstack.backup.veeam.api.Task;
|
||||
import org.apache.cloudstack.utils.security.SSLUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.nio.TrustAllManager;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
public class VeeamClient {
|
||||
private static final Logger LOG = Logger.getLogger(VeeamClient.class);
|
||||
|
||||
private final URI apiURI;
|
||||
|
||||
private final HttpClient httpClient;
|
||||
private static final String RESTORE_VM_SUFFIX = "CS-RSTR-";
|
||||
private static final String SESSION_HEADER = "X-RestSvcSessionId";
|
||||
|
||||
private String veeamServerIp;
|
||||
private String veeamServerUsername;
|
||||
private String veeamServerPassword;
|
||||
private String veeamSessionId = null;
|
||||
private final int veeamServerPort = 22;
|
||||
|
||||
public VeeamClient(final String url, final String username, final String password, final boolean validateCertificate, final int timeout) throws URISyntaxException, NoSuchAlgorithmException, KeyManagementException {
|
||||
this.apiURI = new URI(url);
|
||||
|
||||
final RequestConfig config = RequestConfig.custom()
|
||||
.setConnectTimeout(timeout * 1000)
|
||||
.setConnectionRequestTimeout(timeout * 1000)
|
||||
.setSocketTimeout(timeout * 1000)
|
||||
.build();
|
||||
|
||||
if (!validateCertificate) {
|
||||
final SSLContext sslcontext = SSLUtils.getSSLContext();
|
||||
sslcontext.init(null, new X509TrustManager[]{new TrustAllManager()}, new SecureRandom());
|
||||
final SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
|
||||
this.httpClient = HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig(config)
|
||||
.setSSLSocketFactory(factory)
|
||||
.build();
|
||||
} else {
|
||||
this.httpClient = HttpClientBuilder.create()
|
||||
.setDefaultRequestConfig(config)
|
||||
.build();
|
||||
}
|
||||
|
||||
authenticate(username, password);
|
||||
setVeeamSshCredentials(this.apiURI.getHost(), username, password);
|
||||
}
|
||||
|
||||
protected void setVeeamSshCredentials(String hostIp, String username, String password) {
|
||||
this.veeamServerIp = hostIp;
|
||||
this.veeamServerUsername = username;
|
||||
this.veeamServerPassword = password;
|
||||
}
|
||||
|
||||
private void authenticate(final String username, final String password) {
|
||||
// https://helpcenter.veeam.com/docs/backup/rest/http_authentication.html?ver=95u4
|
||||
final HttpPost request = new HttpPost(apiURI.toString() + "/sessionMngr/?v=v1_4");
|
||||
request.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes()));
|
||||
try {
|
||||
final HttpResponse response = httpClient.execute(request);
|
||||
checkAuthFailure(response);
|
||||
veeamSessionId = response.getFirstHeader(SESSION_HEADER).getValue();
|
||||
if (Strings.isNullOrEmpty(veeamSessionId)) {
|
||||
throw new CloudRuntimeException("Veeam Session ID is not available to perform API requests");
|
||||
}
|
||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) {
|
||||
throw new CloudRuntimeException("Failed to create and authenticate Veeam API client, please check the settings.");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
throw new CloudRuntimeException("Failed to authenticate Veeam API service due to:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAuthFailure(final HttpResponse response) {
|
||||
if (response != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
|
||||
throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, "Veeam B&R API call unauthorized, please ask your administrator to fix integration issues.");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkResponseOK(final HttpResponse response) {
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) {
|
||||
LOG.debug("Requested Veeam resource does not exist");
|
||||
return;
|
||||
}
|
||||
if (!(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ||
|
||||
response.getStatusLine().getStatusCode() == HttpStatus.SC_ACCEPTED) &&
|
||||
response.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) {
|
||||
LOG.debug("HTTP request failed, status code is " + response.getStatusLine().getStatusCode() + ", response is: " + response.toString());
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Got invalid API status code returned by the Veeam server");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkResponseTimeOut(final Exception e) {
|
||||
if (e instanceof ConnectTimeoutException || e instanceof SocketTimeoutException) {
|
||||
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "Veeam API operation timed out, please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponse get(final String path) throws IOException {
|
||||
final HttpGet request = new HttpGet(apiURI.toString() + path);
|
||||
request.setHeader(SESSION_HEADER, veeamSessionId);
|
||||
final HttpResponse response = httpClient.execute(request);
|
||||
checkAuthFailure(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private HttpResponse post(final String path, final Object obj) throws IOException {
|
||||
String xml = null;
|
||||
if (obj != null) {
|
||||
XmlMapper xmlMapper = new XmlMapper();
|
||||
xml = xmlMapper.writer()
|
||||
.with(ToXmlGenerator.Feature.WRITE_XML_DECLARATION)
|
||||
.writeValueAsString(obj);
|
||||
// Remove invalid/empty xmlns
|
||||
xml = xml.replace(" xmlns=\"\"", "");
|
||||
}
|
||||
|
||||
final HttpPost request = new HttpPost(apiURI.toString() + path);
|
||||
request.setHeader(SESSION_HEADER, veeamSessionId);
|
||||
request.setHeader("Content-type", "application/xml");
|
||||
if (StringUtils.isNotBlank(xml)) {
|
||||
request.setEntity(new StringEntity(xml));
|
||||
}
|
||||
|
||||
final HttpResponse response = httpClient.execute(request);
|
||||
checkAuthFailure(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
private HttpResponse delete(final String path) throws IOException {
|
||||
final HttpDelete request = new HttpDelete(apiURI.toString() + path);
|
||||
request.setHeader(SESSION_HEADER, veeamSessionId);
|
||||
final HttpResponse response = httpClient.execute(request);
|
||||
checkAuthFailure(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//////////////// Private Veeam Helper Methods /////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private String findDCHierarchy(final String vmwareDcName) {
|
||||
LOG.debug("Trying to find hierarchy ID for vmware datacenter: " + vmwareDcName);
|
||||
|
||||
try {
|
||||
final HttpResponse response = get("/hierarchyRoots");
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
final EntityReferences references = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class);
|
||||
for (final Ref ref : references.getRefs()) {
|
||||
if (ref.getName().equals(vmwareDcName) && ref.getType().equals("HierarchyRootReference")) {
|
||||
return ref.getUid();
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to find hierarchy reference for VMware datacenter " + vmwareDcName + " in Veeam, please ask administrator to check Veeam B&R manager configuration");
|
||||
}
|
||||
|
||||
private String lookupVM(final String hierarchyId, final String vmName) {
|
||||
LOG.debug("Trying to lookup VM from veeam hierarchy:" + hierarchyId + " for vm name:" + vmName);
|
||||
|
||||
try {
|
||||
final HttpResponse response = get(String.format("/lookup?host=%s&type=Vm&name=%s", hierarchyId, vmName));
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
final HierarchyItems items = objectMapper.readValue(response.getEntity().getContent(), HierarchyItems.class);
|
||||
if (items == null || items.getItems() == null || items.getItems().isEmpty()) {
|
||||
throw new CloudRuntimeException("Could not find VM " + vmName + " in Veeam, please ask administrator to check Veeam B&R manager");
|
||||
}
|
||||
for (final HierarchyItem item : items.getItems()) {
|
||||
if (item.getObjectName().equals(vmName) && item.getObjectType().equals("Vm")) {
|
||||
return item.getObjectRef();
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to lookup VM " + vmName + " in Veeam, please ask administrator to check Veeam B&R manager configuration");
|
||||
}
|
||||
|
||||
private Task parseTaskResponse(HttpResponse response) throws IOException {
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
return objectMapper.readValue(response.getEntity().getContent(), Task.class);
|
||||
}
|
||||
|
||||
private RestoreSession parseRestoreSessionResponse(HttpResponse response) throws IOException {
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
return objectMapper.readValue(response.getEntity().getContent(), RestoreSession.class);
|
||||
}
|
||||
|
||||
private boolean checkTaskStatus(final HttpResponse response) throws IOException {
|
||||
final Task task = parseTaskResponse(response);
|
||||
for (int i = 0; i < 120; i++) {
|
||||
final HttpResponse taskResponse = get("/tasks/" + task.getTaskId());
|
||||
final Task polledTask = parseTaskResponse(taskResponse);
|
||||
if (polledTask.getState().equals("Finished")) {
|
||||
final HttpResponse taskDeleteResponse = delete("/tasks/" + task.getTaskId());
|
||||
if (taskDeleteResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NO_CONTENT) {
|
||||
LOG.warn("Operation failed for veeam task id=" + task.getTaskId());
|
||||
}
|
||||
if (polledTask.getResult().getSuccess().equals("true")) {
|
||||
Pair<String, String> pair = getRelatedLinkPair(polledTask.getLink());
|
||||
if (pair != null) {
|
||||
String url = pair.first();
|
||||
String type = pair.second();
|
||||
String path = url.replace(apiURI.toString(), "");
|
||||
if (type.equals("RestoreSession")) {
|
||||
for (int j = 0; j < 120; j++) {
|
||||
HttpResponse relatedResponse = get(path);
|
||||
RestoreSession session = parseRestoreSessionResponse(relatedResponse);
|
||||
if (session.getResult().equals("Success")) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
throw new CloudRuntimeException("Related job type: " + type + " was not successful");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to assign VM to backup offering due to: " + polledTask.getResult().getMessage());
|
||||
}
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.debug("Failed to sleep while polling for Veeam task status due to: ", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Pair<String, String> getRelatedLinkPair(List<Link> links) {
|
||||
for (Link link : links) {
|
||||
if (link.getRel().equals("Related")) {
|
||||
return new Pair<>(link.getHref(), link.getType());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
//////////////// Public Veeam APIs /////////////////////
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
public Ref listBackupRepository(final String backupServerId) {
|
||||
LOG.debug("Trying to list backup repository for backup server id: " + backupServerId);
|
||||
try {
|
||||
final HttpResponse response = get(String.format("/backupServers/%s/repositories", backupServerId));
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
final EntityReferences references = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class);
|
||||
for (final Ref ref : references.getRefs()) {
|
||||
if (ref.getType().equals("RepositoryReference")) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void listAllBackups() {
|
||||
LOG.debug("Trying to list Veeam backups");
|
||||
try {
|
||||
final HttpResponse response = get("/backups");
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
final EntityReferences entityReferences = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class);
|
||||
for (final Ref ref : entityReferences.getRefs()) {
|
||||
LOG.debug("Veeam Backup found, name: " + ref.getName() + ", uid: " + ref.getUid() + ", type: " + ref.getType());
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam backups due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<BackupOffering> listJobs() {
|
||||
LOG.debug("Trying to list backup policies that are Veeam jobs");
|
||||
try {
|
||||
final HttpResponse response = get("/jobs");
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
final EntityReferences entityReferences = objectMapper.readValue(response.getEntity().getContent(), EntityReferences.class);
|
||||
final List<BackupOffering> policies = new ArrayList<>();
|
||||
if (entityReferences == null || entityReferences.getRefs() == null) {
|
||||
return policies;
|
||||
}
|
||||
for (final Ref ref : entityReferences.getRefs()) {
|
||||
policies.add(new VeeamBackupOffering(ref.getName(), ref.getUid()));
|
||||
}
|
||||
return policies;
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public Job listJob(final String jobId) {
|
||||
LOG.debug("Trying to list veeam job id: " + jobId);
|
||||
try {
|
||||
final HttpResponse response = get(String.format("/jobs/%s?format=Entity",
|
||||
jobId.replace("urn:veeam:Job:", "")));
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
return objectMapper.readValue(response.getEntity().getContent(), Job.class);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
} catch (final ServerApiException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean toggleJobSchedule(final String jobId) {
|
||||
LOG.debug("Trying to toggle schedule for Veeam job: " + jobId);
|
||||
try {
|
||||
final HttpResponse response = post(String.format("/jobs/%s?action=toggleScheduleEnabled", jobId), null);
|
||||
return checkTaskStatus(response);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to toggle Veeam job schedule due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean startBackupJob(final String jobId) {
|
||||
LOG.debug("Trying to start ad-hoc backup for Veeam job: " + jobId);
|
||||
try {
|
||||
final HttpResponse response = post(String.format("/jobs/%s?action=start", jobId), null);
|
||||
return checkTaskStatus(response);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean cloneVeeamJob(final Job parentJob, final String clonedJobName) {
|
||||
LOG.debug("Trying to clone veeam job: " + parentJob.getUid() + " with backup uuid: " + clonedJobName);
|
||||
try {
|
||||
final Ref repositoryRef = listBackupRepository(parentJob.getBackupServerId());
|
||||
final BackupJobCloneInfo cloneInfo = new BackupJobCloneInfo();
|
||||
cloneInfo.setJobName(clonedJobName);
|
||||
cloneInfo.setFolderName(clonedJobName);
|
||||
cloneInfo.setRepositoryUid(repositoryRef.getUid());
|
||||
final JobCloneSpec cloneSpec = new JobCloneSpec(cloneInfo);
|
||||
final HttpResponse response = post(String.format("/jobs/%s?action=clone", parentJob.getId()), cloneSpec);
|
||||
return checkTaskStatus(response);
|
||||
} catch (final Exception e) {
|
||||
LOG.warn("Exception caught while trying to clone Veeam job:", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addVMToVeeamJob(final String jobId, final String vmwareInstanceName, final String vmwareDcName) {
|
||||
LOG.debug("Trying to add VM to backup offering that is Veeam job: " + jobId);
|
||||
try {
|
||||
final String heirarchyId = findDCHierarchy(vmwareDcName);
|
||||
final String veeamVmRefId = lookupVM(heirarchyId, vmwareInstanceName);
|
||||
final CreateObjectInJobSpec vmToBackupJob = new CreateObjectInJobSpec();
|
||||
vmToBackupJob.setObjName(vmwareInstanceName);
|
||||
vmToBackupJob.setObjRef(veeamVmRefId);
|
||||
final HttpResponse response = post(String.format("/jobs/%s/includes", jobId), vmToBackupJob);
|
||||
return checkTaskStatus(response);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to add VM to Veeam job due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to add VM to backup offering likely due to timeout, please check Veeam tasks");
|
||||
}
|
||||
|
||||
public boolean removeVMFromVeeamJob(final String jobId, final String vmwareInstanceName, final String vmwareDcName) {
|
||||
LOG.debug("Trying to remove VM from backup offering that is a Veeam job: " + jobId);
|
||||
try {
|
||||
final String hierarchyId = findDCHierarchy(vmwareDcName);
|
||||
final String veeamVmRefId = lookupVM(hierarchyId, vmwareInstanceName);
|
||||
final HttpResponse response = get(String.format("/jobs/%s/includes", jobId));
|
||||
checkResponseOK(response);
|
||||
final ObjectMapper objectMapper = new XmlMapper();
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
final ObjectsInJob jobObjects = objectMapper.readValue(response.getEntity().getContent(), ObjectsInJob.class);
|
||||
if (jobObjects == null || jobObjects.getObjects() == null) {
|
||||
LOG.warn("No objects found in the Veeam job " + jobId);
|
||||
return false;
|
||||
}
|
||||
for (final ObjectInJob jobObject : jobObjects.getObjects()) {
|
||||
if (jobObject.getName().equals(vmwareInstanceName) && jobObject.getHierarchyObjRef().equals(veeamVmRefId)) {
|
||||
final HttpResponse deleteResponse = delete(String.format("/jobs/%s/includes/%s", jobId, jobObject.getObjectInJobId()));
|
||||
return checkTaskStatus(deleteResponse);
|
||||
}
|
||||
}
|
||||
LOG.warn(vmwareInstanceName + " VM was not found to be attached to Veaam job (backup offering): " + jobId);
|
||||
return false;
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to list Veeam jobs due to:", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean restoreFullVM(final String vmwareInstanceName, final String restorePointId) {
|
||||
LOG.debug("Trying to restore full VM: " + vmwareInstanceName + " from backup");
|
||||
try {
|
||||
final HttpResponse response = post(String.format("/vmRestorePoints/%s?action=restore", restorePointId), null);
|
||||
return checkTaskStatus(response);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to restore full VM due to: ", e);
|
||||
checkResponseTimeOut(e);
|
||||
}
|
||||
throw new CloudRuntimeException("Failed to restore full VM from backup");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//////////////// Public Veeam PS based APIs /////////////////////
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Generate a single command to be passed through SSH
|
||||
*/
|
||||
protected String transformPowerShellCommandList(List<String> cmds) {
|
||||
StringJoiner joiner = new StringJoiner(";");
|
||||
joiner.add("PowerShell Add-PSSnapin VeeamPSSnapin");
|
||||
for (String cmd : cmds) {
|
||||
joiner.add(cmd);
|
||||
}
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a list of commands in a single call on PowerShell through SSH
|
||||
*/
|
||||
protected Pair<Boolean, String> executePowerShellCommands(List<String> cmds) {
|
||||
try {
|
||||
Pair<Boolean, String> pairResult = SshHelper.sshExecute(veeamServerIp, veeamServerPort,
|
||||
veeamServerUsername, null, veeamServerPassword,
|
||||
transformPowerShellCommandList(cmds),
|
||||
120000, 120000, 3600000);
|
||||
return pairResult;
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Error while executing PowerShell commands due to: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setJobSchedule(final String jobName) {
|
||||
Pair<Boolean, String> result = executePowerShellCommands(Arrays.asList(
|
||||
String.format("$job = Get-VBRJob -Name \"%s\"", jobName),
|
||||
"if ($job) { Set-VBRJobSchedule -Job $job -Daily -At \"11:00\" -DailyKind Weekdays }"
|
||||
));
|
||||
return result.first() && !result.second().isEmpty() && !result.second().contains("Failed to delete");
|
||||
}
|
||||
|
||||
public boolean deleteJobAndBackup(final String jobName) {
|
||||
Pair<Boolean, String> result = executePowerShellCommands(Arrays.asList(
|
||||
String.format("$job = Get-VBRJob -Name \"%s\"", jobName),
|
||||
"if ($job) { Remove-VBRJob -Job $job -Confirm:$false }",
|
||||
String.format("$backup = Get-VBRBackup -Name \"%s\"", jobName),
|
||||
"if ($backup) { Remove-VBRBackup -Backup $backup -FromDisk -Confirm:$false }",
|
||||
"$repo = Get-VBRBackupRepository",
|
||||
"Sync-VBRBackupRepository -Repository $repo"
|
||||
));
|
||||
return result.first() && !result.second().contains("Failed to delete");
|
||||
}
|
||||
|
||||
public Map<String, Backup.Metric> getBackupMetrics() {
|
||||
final String separator = "=====";
|
||||
final List<String> cmds = Arrays.asList(
|
||||
"$backups = Get-VBRBackup",
|
||||
"foreach ($backup in $backups) {" +
|
||||
"$backup.JobName;" +
|
||||
"$storageGroups = $backup.GetStorageGroups();" +
|
||||
"foreach ($group in $storageGroups) {" +
|
||||
"$usedSize = 0;" +
|
||||
"$dataSize = 0;" +
|
||||
"$sizePerStorage = $group.GetStorages().Stats.BackupSize;" +
|
||||
"$dataPerStorage = $group.GetStorages().Stats.DataSize;" +
|
||||
"foreach ($size in $sizePerStorage) {" +
|
||||
"$usedSize += $size;" +
|
||||
"}" +
|
||||
"foreach ($size in $dataPerStorage) {" +
|
||||
"$dataSize += $size;" +
|
||||
"}" +
|
||||
"$usedSize;" +
|
||||
"$dataSize;" +
|
||||
"}" +
|
||||
"echo \"" + separator + "\"" +
|
||||
"}"
|
||||
);
|
||||
Pair<Boolean, String> response = executePowerShellCommands(cmds);
|
||||
final Map<String, Backup.Metric> sizes = new HashMap<>();
|
||||
for (final String block : response.second().split(separator + "\r\n")) {
|
||||
final String[] parts = block.split("\r\n");
|
||||
if (parts.length != 3) {
|
||||
continue;
|
||||
}
|
||||
final String backupName = parts[0];
|
||||
if (backupName != null && backupName.contains(BACKUP_IDENTIFIER)) {
|
||||
final String[] names = backupName.split(BACKUP_IDENTIFIER);
|
||||
sizes.put(names[names.length - 1], new Backup.Metric(Long.valueOf(parts[1]), Long.valueOf(parts[2])));
|
||||
}
|
||||
}
|
||||
return sizes;
|
||||
}
|
||||
|
||||
private Backup.RestorePoint getRestorePointFromBlock(String[] parts) {
|
||||
String id = null;
|
||||
String created = null;
|
||||
String type = null;
|
||||
for (String part : parts) {
|
||||
if (part.matches("Id(\\s)+:(.)*")) {
|
||||
String[] split = part.split(":");
|
||||
id = split[1].trim();
|
||||
} else if (part.matches("CreationTime(\\s)+:(.)*")) {
|
||||
String [] split = part.split(":", 2);
|
||||
created = split[1].trim();
|
||||
} else if (part.matches("Type(\\s)+:(.)*")) {
|
||||
String [] split = part.split(":");
|
||||
type = split[1].trim();
|
||||
}
|
||||
}
|
||||
return new Backup.RestorePoint(id, created, type);
|
||||
}
|
||||
|
||||
public List<Backup.RestorePoint> listRestorePoints(String backupName, String vmInternalName) {
|
||||
final List<String> cmds = Arrays.asList(
|
||||
String.format("$backup = Get-VBRBackup -Name \"%s\"", backupName),
|
||||
String.format("if ($backup) { (Get-VBRRestorePoint -Backup:$backup -Name \"%s\" ^| Where-Object {$_.IsConsistent -eq $true}) }", vmInternalName)
|
||||
);
|
||||
Pair<Boolean, String> response = executePowerShellCommands(cmds);
|
||||
final List<Backup.RestorePoint> restorePoints = new ArrayList<>();
|
||||
if (response == null || !response.first()) {
|
||||
LOG.debug("Veeam restore point listing failed due to: " + (response != null ? response.second() : "no powershell output returned"));
|
||||
return restorePoints;
|
||||
}
|
||||
for (final String block : response.second().split("\r\n\r\n")) {
|
||||
if (block.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
final String[] parts = block.split("\r\n");
|
||||
restorePoints.add(getRestorePointFromBlock(parts));
|
||||
}
|
||||
return restorePoints;
|
||||
}
|
||||
|
||||
public Pair<Boolean, String> restoreVMToDifferentLocation(String restorePointId, String hostIp, String dataStoreUuid) {
|
||||
final String restoreLocation = RESTORE_VM_SUFFIX + UUID.randomUUID().toString();
|
||||
final String datastoreId = dataStoreUuid.replace("-","");
|
||||
final List<String> cmds = Arrays.asList(
|
||||
"$points = Get-VBRRestorePoint",
|
||||
String.format("foreach($point in $points) { if ($point.Id -eq '%s') { break; } }", restorePointId),
|
||||
String.format("$server = Get-VBRServer -Name \"%s\"", hostIp),
|
||||
String.format("$ds = Find-VBRViDatastore -Server:$server -Name \"%s\"", datastoreId),
|
||||
String.format("$job = Start-VBRRestoreVM -RestorePoint:$point -Server:$server -Datastore:$ds -VMName \"%s\" -RunAsync", restoreLocation),
|
||||
"while (-not (Get-VBRRestoreSession -Id $job.Id).IsCompleted) { Start-Sleep -Seconds 10 }"
|
||||
);
|
||||
Pair<Boolean, String> result = executePowerShellCommands(cmds);
|
||||
if (result == null || !result.first()) {
|
||||
throw new CloudRuntimeException("Failed to restore VM to location " + restoreLocation);
|
||||
}
|
||||
return new Pair<>(result.first(), restoreLocation);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
// 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.backup.veeam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VeeamObject {
|
||||
String getUuid();
|
||||
String getName();
|
||||
String getHref();
|
||||
String getType();
|
||||
List<VeeamObject> getLinks();
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "BackupJobCloneInfo")
|
||||
public class BackupJobCloneInfo {
|
||||
|
||||
@JacksonXmlProperty(localName = "JobName")
|
||||
private String jobName;
|
||||
|
||||
@JacksonXmlProperty(localName = "FolderName")
|
||||
private String folderName;
|
||||
|
||||
@JacksonXmlProperty(localName = "RepositoryUid")
|
||||
private String repositoryUid;
|
||||
|
||||
public String getJobName() {
|
||||
return jobName;
|
||||
}
|
||||
|
||||
public void setJobName(String jobName) {
|
||||
this.jobName = jobName;
|
||||
}
|
||||
|
||||
public String getFolderName() {
|
||||
return folderName;
|
||||
}
|
||||
|
||||
public void setFolderName(String folderName) {
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
public String getRepositoryUid() {
|
||||
return repositoryUid;
|
||||
}
|
||||
|
||||
public void setRepositoryUid(String repositoryUid) {
|
||||
this.repositoryUid = repositoryUid;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "CreateObjectInJobSpec", namespace = "http://www.veeam.com/ent/v1.0")
|
||||
public class CreateObjectInJobSpec {
|
||||
@JacksonXmlProperty(localName = "HierarchyObjRef")
|
||||
String objRef;
|
||||
|
||||
@JacksonXmlProperty(localName = "HierarchyObjName")
|
||||
String objName;
|
||||
|
||||
public String getObjRef() {
|
||||
return objRef;
|
||||
}
|
||||
|
||||
public void setObjRef(String objRef) {
|
||||
this.objRef = objRef;
|
||||
}
|
||||
|
||||
public String getObjName() {
|
||||
return objName;
|
||||
}
|
||||
|
||||
public void setObjName(String objName) {
|
||||
this.objName = objName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "EntityReferences")
|
||||
public class EntityReferences {
|
||||
@JacksonXmlProperty(localName = "Ref")
|
||||
@JacksonXmlElementWrapper(localName = "Ref", useWrapping = false)
|
||||
private List<Ref> refs;
|
||||
|
||||
public List<Ref> getRefs() {
|
||||
return refs;
|
||||
}
|
||||
|
||||
public void setRefs(List<Ref> refs) {
|
||||
this.refs = refs;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "HierarchyItem")
|
||||
public class HierarchyItem {
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "ObjectRef")
|
||||
private String objectRef;
|
||||
|
||||
@JacksonXmlProperty(localName = "ObjectType")
|
||||
private String objectType;
|
||||
|
||||
@JacksonXmlProperty(localName = "ObjectName")
|
||||
private String objectName;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getObjectRef() {
|
||||
return objectRef;
|
||||
}
|
||||
|
||||
public void setObjectRef(String objectRef) {
|
||||
this.objectRef = objectRef;
|
||||
}
|
||||
|
||||
public String getObjectType() {
|
||||
return objectType;
|
||||
}
|
||||
|
||||
public void setObjectType(String objectType) {
|
||||
this.objectType = objectType;
|
||||
}
|
||||
|
||||
public String getObjectName() {
|
||||
return objectName;
|
||||
}
|
||||
|
||||
public void setObjectName(String objectName) {
|
||||
this.objectName = objectName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "HierarchyItems")
|
||||
public class HierarchyItems {
|
||||
@JacksonXmlProperty(localName = "HierarchyItem")
|
||||
@JacksonXmlElementWrapper(localName = "HierarchyItem", useWrapping = false)
|
||||
private List<HierarchyItem> items;
|
||||
|
||||
public List<HierarchyItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<HierarchyItem> items) {
|
||||
this.items = items;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Job")
|
||||
public class Job {
|
||||
|
||||
@JacksonXmlProperty(localName = "Name", isAttribute = true)
|
||||
private String name;
|
||||
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "UID", isAttribute = true)
|
||||
private String uid;
|
||||
|
||||
@JacksonXmlProperty(localName = "Link")
|
||||
@JacksonXmlElementWrapper(localName = "Links")
|
||||
private List<Link> link;
|
||||
|
||||
@JacksonXmlProperty(localName = "Platform")
|
||||
private String platform;
|
||||
|
||||
@JacksonXmlProperty(localName = "Description")
|
||||
private String description;
|
||||
|
||||
@JacksonXmlProperty(localName = "NextRun")
|
||||
private String nextRun;
|
||||
|
||||
@JacksonXmlProperty(localName = "JobType")
|
||||
private String jobType;
|
||||
|
||||
@JacksonXmlProperty(localName = "ScheduleEnabled")
|
||||
private Boolean scheduleEnabled;
|
||||
|
||||
@JacksonXmlProperty(localName = "ScheduleConfigured")
|
||||
private Boolean scheduleConfigured;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return uid.replace("urn:veeam:Job:", "");
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public List<Link> getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(List<Link> link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getNextRun() {
|
||||
return nextRun;
|
||||
}
|
||||
|
||||
public void setNextRun(String nextRun) {
|
||||
this.nextRun = nextRun;
|
||||
}
|
||||
|
||||
public String getJobType() {
|
||||
return jobType;
|
||||
}
|
||||
|
||||
public void setJobType(String jobType) {
|
||||
this.jobType = jobType;
|
||||
}
|
||||
|
||||
public String getBackupServerId() {
|
||||
for (final Link l : link) {
|
||||
if (l.getType().equals("BackupServerReference")) {
|
||||
return "" + l.getHref().split("backupServers/")[1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Boolean getScheduleEnabled() {
|
||||
return scheduleEnabled;
|
||||
}
|
||||
|
||||
public void setScheduleEnabled(String scheduleEnabled) {
|
||||
this.scheduleEnabled = Boolean.valueOf(scheduleEnabled);
|
||||
}
|
||||
|
||||
public Boolean getScheduleConfigured() {
|
||||
return scheduleConfigured;
|
||||
}
|
||||
|
||||
public void setScheduleConfigured(String scheduleConfigured) {
|
||||
this.scheduleConfigured = Boolean.valueOf(scheduleConfigured);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "JobCloneSpec", namespace = "http://www.veeam.com/ent/v1.0")
|
||||
public class JobCloneSpec {
|
||||
@JacksonXmlProperty(localName = "BackupJobCloneInfo")
|
||||
@JacksonXmlElementWrapper(localName = "BackupJobCloneInfo", useWrapping = false)
|
||||
BackupJobCloneInfo jobCloneInfo;
|
||||
|
||||
public JobCloneSpec(final BackupJobCloneInfo jobCloneInfo) {
|
||||
this.jobCloneInfo = jobCloneInfo;
|
||||
}
|
||||
|
||||
public BackupJobCloneInfo getJobCloneInfo() {
|
||||
return jobCloneInfo;
|
||||
}
|
||||
|
||||
public void setJobCloneInfo(BackupJobCloneInfo jobCloneInfo) {
|
||||
this.jobCloneInfo = jobCloneInfo;
|
||||
}
|
||||
}
|
||||
@ -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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Link")
|
||||
public class Link {
|
||||
|
||||
@JacksonXmlProperty(localName = "Name", isAttribute = true)
|
||||
private String name;
|
||||
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "Rel", isAttribute = true)
|
||||
private String rel;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getRel() {
|
||||
return rel;
|
||||
}
|
||||
|
||||
public void setRel(String rel) {
|
||||
this.rel = rel;
|
||||
}
|
||||
}
|
||||
@ -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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "ObjectInJob")
|
||||
public class ObjectInJob {
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "Link")
|
||||
@JacksonXmlElementWrapper(localName = "Links")
|
||||
private List<Link> link;
|
||||
|
||||
@JacksonXmlProperty(localName = "ObjectInJobId", isAttribute = true)
|
||||
private String objectInJobId;
|
||||
|
||||
@JacksonXmlProperty(localName = "HierarchyObjRef", isAttribute = true)
|
||||
private String hierarchyObjRef;
|
||||
|
||||
@JacksonXmlProperty(localName = "Name", isAttribute = true)
|
||||
private String name;
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public List<Link> getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(List<Link> link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getObjectInJobId() {
|
||||
return objectInJobId;
|
||||
}
|
||||
|
||||
public void setObjectInJobId(String objectInJobId) {
|
||||
this.objectInJobId = objectInJobId;
|
||||
}
|
||||
|
||||
public String getHierarchyObjRef() {
|
||||
return hierarchyObjRef;
|
||||
}
|
||||
|
||||
public void setHierarchyObjRef(String hierarchyObjRef) {
|
||||
this.hierarchyObjRef = hierarchyObjRef;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "ObjectsInJob")
|
||||
public class ObjectsInJob {
|
||||
@JacksonXmlProperty(localName = "ObjectInJob")
|
||||
@JacksonXmlElementWrapper(localName = "ObjectInJob", useWrapping = false)
|
||||
private List<ObjectInJob> objects;
|
||||
|
||||
public List<ObjectInJob> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public void setObjects(List<ObjectInJob> objects) {
|
||||
this.objects = objects;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Ref")
|
||||
public class Ref {
|
||||
@JacksonXmlProperty(localName = "UID", isAttribute = true)
|
||||
private String uid;
|
||||
|
||||
@JacksonXmlProperty(localName = "Name", isAttribute = true)
|
||||
private String name;
|
||||
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "Link")
|
||||
@JacksonXmlElementWrapper(localName = "Links")
|
||||
private List<Link> link;
|
||||
|
||||
public List<Link> getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(List<Link> link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JacksonXmlRootElement(localName = "RestoreSession")
|
||||
public class RestoreSession {
|
||||
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Name", isAttribute = true)
|
||||
private String name;
|
||||
|
||||
@JacksonXmlProperty(localName = "UID", isAttribute = true)
|
||||
private String uid;
|
||||
|
||||
@JacksonXmlProperty(localName = "VmDisplayName", isAttribute = true)
|
||||
private String vmDisplayName;
|
||||
|
||||
@JacksonXmlProperty(localName = "Link")
|
||||
@JacksonXmlElementWrapper(localName = "Links")
|
||||
private List<Link> link;
|
||||
|
||||
@JacksonXmlProperty(localName = "JobType")
|
||||
private String jobType;
|
||||
|
||||
@JacksonXmlProperty(localName = "CreationTimeUTC")
|
||||
private String creationTimeUTC;
|
||||
|
||||
@JacksonXmlProperty(localName = "EndTimeUTC")
|
||||
private String endTimeUTC;
|
||||
|
||||
@JacksonXmlProperty(localName = "State")
|
||||
private String state;
|
||||
|
||||
@JacksonXmlProperty(localName = "Result")
|
||||
private String result;
|
||||
|
||||
@JacksonXmlProperty(localName = "Progress")
|
||||
private String progress;
|
||||
|
||||
@JacksonXmlProperty(localName = "RestoredObjRef")
|
||||
private String restoredObjRef;
|
||||
|
||||
public List<Link> getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public String getJobType() {
|
||||
return jobType;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public String getVmDisplayName() {
|
||||
return vmDisplayName;
|
||||
}
|
||||
|
||||
public String getCreationTimeUTC() {
|
||||
return creationTimeUTC;
|
||||
}
|
||||
|
||||
public String getEndTimeUTC() {
|
||||
return endTimeUTC;
|
||||
}
|
||||
|
||||
public String getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public String getRestoredObjRef() {
|
||||
return restoredObjRef;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
// 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.backup.veeam.api;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "Result")
|
||||
public class Result {
|
||||
|
||||
@JacksonXmlProperty(localName = "Success", isAttribute = true)
|
||||
private String success;
|
||||
|
||||
@JacksonXmlProperty(localName = "Message")
|
||||
private String message;
|
||||
|
||||
public String getSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(String success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@ -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.backup.veeam.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
|
||||
|
||||
@JacksonXmlRootElement(localName = "CreateObjectInJobSpec")
|
||||
public class Task {
|
||||
@JacksonXmlProperty(localName = "Type", isAttribute = true)
|
||||
private String type;
|
||||
|
||||
@JacksonXmlProperty(localName = "Href", isAttribute = true)
|
||||
private String href;
|
||||
|
||||
@JacksonXmlProperty(localName = "Link")
|
||||
@JacksonXmlElementWrapper(localName = "Links")
|
||||
private List<Link> link;
|
||||
|
||||
@JacksonXmlProperty(localName = "TaskId")
|
||||
private String taskId;
|
||||
|
||||
@JacksonXmlProperty(localName = "State")
|
||||
private String state;
|
||||
|
||||
@JacksonXmlProperty(localName = "Operation")
|
||||
private String operation;
|
||||
|
||||
@JacksonXmlProperty(localName = "Result")
|
||||
@JacksonXmlElementWrapper(localName = "Result", useWrapping = false)
|
||||
private Result result;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public List<Link> getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(List<Link> link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getTaskId() {
|
||||
return taskId;
|
||||
}
|
||||
|
||||
public void setTaskId(String taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Result result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user