Skip to content

Commit 1ad120f

Browse files
committed
add support for vpc & backup offerings to be cloned
1 parent 2afc1b7 commit 1ad120f

File tree

12 files changed

+605
-11
lines changed

12 files changed

+605
-11
lines changed

api/src/main/java/com/cloud/event/EventTypes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ public class EventTypes {
629629

630630
// Backup and Recovery events
631631
public static final String EVENT_VM_BACKUP_IMPORT_OFFERING = "BACKUP.IMPORT.OFFERING";
632+
public static final String EVENT_VM_BACKUP_CLONE_OFFERING = "BACKUP.CLONE.OFFERING";
632633
public static final String EVENT_VM_BACKUP_OFFERING_ASSIGN = "BACKUP.OFFERING.ASSIGN";
633634
public static final String EVENT_VM_BACKUP_OFFERING_REMOVE = "BACKUP.OFFERING.REMOVE";
634635
public static final String EVENT_VM_BACKUP_CREATE = "BACKUP.CREATE";

api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import org.apache.cloudstack.api.command.admin.vpc.CloneVPCOfferingCmd;
2324
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
2425
import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
2526
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
@@ -34,6 +35,8 @@ public interface VpcProvisioningService {
3435

3536
VpcOffering createVpcOffering(CreateVPCOfferingCmd cmd);
3637

38+
VpcOffering cloneVPCOffering(CloneVPCOfferingCmd cmd);
39+
3740
VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
3841
Map<String, List<String>> serviceProviders,
3942
Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol,
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.admin.backup;
18+
19+
import org.apache.cloudstack.acl.RoleType;
20+
import org.apache.cloudstack.api.APICommand;
21+
import org.apache.cloudstack.api.ApiConstants;
22+
import org.apache.cloudstack.api.ApiErrorCode;
23+
import org.apache.cloudstack.api.Parameter;
24+
import org.apache.cloudstack.api.ServerApiException;
25+
import org.apache.cloudstack.api.response.BackupOfferingResponse;
26+
import org.apache.cloudstack.backup.BackupOffering;
27+
28+
import com.cloud.event.EventTypes;
29+
import com.cloud.exception.ConcurrentOperationException;
30+
import com.cloud.exception.InsufficientCapacityException;
31+
import com.cloud.exception.InvalidParameterValueException;
32+
import com.cloud.exception.NetworkRuleConflictException;
33+
import com.cloud.exception.ResourceAllocationException;
34+
import com.cloud.exception.ResourceUnavailableException;
35+
import com.cloud.utils.exception.CloudRuntimeException;
36+
37+
@APICommand(name = "cloneBackupOffering",
38+
description = "Clones an existing backup offering with updated values. " +
39+
"All parameters are copied from the source offering unless explicitly overridden.",
40+
responseObject = BackupOfferingResponse.class,
41+
since = "4.23.0",
42+
authorized = {RoleType.Admin})
43+
public class CloneBackupOfferingCmd extends ImportBackupOfferingCmd {
44+
45+
/////////////////////////////////////////////////////
46+
//////////////// API parameters /////////////////////
47+
/////////////////////////////////////////////////////
48+
49+
@Parameter(name = ApiConstants.ID,
50+
type = CommandType.UUID,
51+
entityType = BackupOfferingResponse.class,
52+
required = true,
53+
description = "The ID of the backup offering to clone")
54+
private Long id;
55+
56+
/////////////////////////////////////////////////////
57+
/////////////////// Accessors ///////////////////////
58+
/////////////////////////////////////////////////////
59+
60+
public Long getId() {
61+
return id;
62+
}
63+
64+
65+
/////////////////////////////////////////////////////
66+
/////////////// API Implementation///////////////////
67+
/////////////////////////////////////////////////////
68+
69+
@Override
70+
public void execute() throws ResourceUnavailableException, InsufficientCapacityException,
71+
ServerApiException, ConcurrentOperationException, ResourceAllocationException,
72+
NetworkRuleConflictException {
73+
try {
74+
BackupOffering clonedOffering = backupManager.cloneBackupOffering(this);
75+
if (clonedOffering != null) {
76+
BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(clonedOffering);
77+
response.setResponseName(getCommandName());
78+
setResponseObject(response);
79+
} else {
80+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone backup offering");
81+
}
82+
} catch (InvalidParameterValueException e) {
83+
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
84+
} catch (CloudRuntimeException e) {
85+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
86+
}
87+
}
88+
89+
@Override
90+
public String getEventType() {
91+
return EventTypes.EVENT_VM_BACKUP_CLONE_OFFERING;
92+
}
93+
94+
@Override
95+
public String getEventDescription() {
96+
return "Cloning backup offering from ID: " + id + " to new offering: " + getName();
97+
}
98+
}
99+

api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ImportBackupOfferingCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
public class ImportBackupOfferingCmd extends BaseAsyncCmd {
4949

5050
@Inject
51-
private BackupManager backupManager;
51+
protected BackupManager backupManager;
5252

5353
/////////////////////////////////////////////////////
5454
//////////////// API parameters /////////////////////

api/src/main/java/org/apache/cloudstack/api/command/admin/network/CloneNetworkOfferingCmd.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public class CloneNetworkOfferingCmd extends CreateNetworkOfferingCmd {
6262
"If specified along with 'supportedservices', this parameter is ignored.")
6363
private List<String> dropServices;
6464

65+
6566
/////////////////////////////////////////////////////
6667
/////////////////// Accessors ///////////////////////
6768
/////////////////////////////////////////////////////
@@ -78,6 +79,24 @@ public List<String> getDropServices() {
7879
return dropServices;
7980
}
8081

82+
/**
83+
* Override to provide placeholder values that will be replaced with source offering values.
84+
* This allows API validation to pass even though these are marked as required in the parent class.
85+
*/
86+
@Override
87+
public String getGuestIpType() {
88+
String value = super.getGuestIpType();
89+
// Return placeholder if not provided - will be overwritten from source offering
90+
return value != null ? value : "Isolated";
91+
}
92+
93+
@Override
94+
public String getTraffictype() {
95+
String value = super.getTraffictype();
96+
// Return placeholder if not provided - will be overwritten from source offering
97+
return value != null ? value : "Guest";
98+
}
99+
81100
/////////////////////////////////////////////////////
82101
/////////////// API Implementation///////////////////
83102
/////////////////////////////////////////////////////

api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
128128
private Map serviceProviderList;
129129

130130
@Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "Desired service capabilities as part of network offering")
131-
private Map serviceCapabilitystList;
131+
private Map serviceCapabilitiesList;
132132

133133
@Parameter(name = ApiConstants.SPECIFY_IP_RANGES,
134134
type = CommandType.BOOLEAN,
@@ -423,9 +423,9 @@ else if (NetworkOffering.NetworkMode.NATTED.name().equalsIgnoreCase(getNetworkMo
423423
public Map<Capability, String> getServiceCapabilities(Service service) {
424424
Map<Capability, String> capabilityMap = null;
425425

426-
if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
426+
if (serviceCapabilitiesList != null && !serviceCapabilitiesList.isEmpty()) {
427427
capabilityMap = new HashMap<Capability, String>();
428-
Collection serviceCapabilityCollection = serviceCapabilitystList.values();
428+
Collection serviceCapabilityCollection = serviceCapabilitiesList.values();
429429
Iterator iter = serviceCapabilityCollection.iterator();
430430
while (iter.hasNext()) {
431431
HashMap<String, String> svcCapabilityMap = (HashMap<String, String>) iter.next();
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.api.command.admin.vpc;
18+
19+
import com.cloud.network.vpc.VpcOffering;
20+
import org.apache.cloudstack.api.APICommand;
21+
import org.apache.cloudstack.api.ApiConstants;
22+
import org.apache.cloudstack.api.ApiErrorCode;
23+
import org.apache.cloudstack.api.BaseCmd;
24+
import org.apache.cloudstack.api.Parameter;
25+
import org.apache.cloudstack.api.ServerApiException;
26+
import org.apache.cloudstack.api.response.VpcOfferingResponse;
27+
28+
import java.util.List;
29+
30+
@APICommand(name = "cloneVPCOffering",
31+
description = "Clones an existing VPC offering. All parameters are copied from the source offering unless explicitly overridden. " +
32+
"Use 'addServices' and 'dropServices' to modify the service list without respecifying everything.",
33+
responseObject = VpcOfferingResponse.class,
34+
requestHasSensitiveInfo = false,
35+
responseHasSensitiveInfo = false,
36+
since = "4.23.0")
37+
public class CloneVPCOfferingCmd extends CreateVPCOfferingCmd {
38+
39+
/////////////////////////////////////////////////////
40+
//////////////// API parameters /////////////////////
41+
/////////////////////////////////////////////////////
42+
43+
@Parameter(name = ApiConstants.SOURCE_OFFERING_ID,
44+
type = BaseCmd.CommandType.UUID,
45+
entityType = VpcOfferingResponse.class,
46+
required = true,
47+
description = "The ID of the VPC offering to clone")
48+
private Long sourceOfferingId;
49+
50+
@Parameter(name = "addservices",
51+
type = CommandType.LIST,
52+
collectionType = CommandType.STRING,
53+
description = "Services to add to the cloned offering (in addition to source offering services). " +
54+
"If specified along with 'supportedservices', this parameter is ignored.")
55+
private List<String> addServices;
56+
57+
@Parameter(name = "dropservices",
58+
type = CommandType.LIST,
59+
collectionType = CommandType.STRING,
60+
description = "Services to remove from the cloned offering (that exist in source offering). " +
61+
"If specified along with 'supportedservices', this parameter is ignored.")
62+
private List<String> dropServices;
63+
64+
/////////////////////////////////////////////////////
65+
/////////////////// Accessors ///////////////////////
66+
/////////////////////////////////////////////////////
67+
68+
public Long getSourceOfferingId() {
69+
return sourceOfferingId;
70+
}
71+
72+
public List<String> getAddServices() {
73+
return addServices;
74+
}
75+
76+
public List<String> getDropServices() {
77+
return dropServices;
78+
}
79+
80+
/////////////////////////////////////////////////////
81+
/////////////// API Implementation///////////////////
82+
/////////////////////////////////////////////////////
83+
84+
@Override
85+
public void execute() {
86+
VpcOffering result = _vpcProvSvc.cloneVPCOffering(this);
87+
if (result != null) {
88+
VpcOfferingResponse response = _responseGenerator.createVpcOfferingResponse(result);
89+
response.setResponseName(getCommandName());
90+
this.setResponseObject(response);
91+
} else {
92+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone VPC offering");
93+
}
94+
}
95+
}

api/src/main/java/org/apache/cloudstack/backup/BackupManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import com.cloud.capacity.Capacity;
2424
import com.cloud.exception.ResourceAllocationException;
25+
import org.apache.cloudstack.api.command.admin.backup.CloneBackupOfferingCmd;
2526
import org.apache.cloudstack.api.command.admin.backup.ImportBackupOfferingCmd;
2627
import org.apache.cloudstack.api.command.admin.backup.UpdateBackupOfferingCmd;
2728
import org.apache.cloudstack.api.command.user.backup.CreateBackupCmd;
@@ -136,6 +137,12 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
136137
*/
137138
BackupOffering importBackupOffering(final ImportBackupOfferingCmd cmd);
138139

140+
/**
141+
* Clone an existing backup offering with updated values
142+
* @param cmd clone backup offering cmd
143+
*/
144+
BackupOffering cloneBackupOffering(final CloneBackupOfferingCmd cmd);
145+
139146
/**
140147
* List backup offerings
141148
* @param ListBackupOfferingsCmd API cmd

0 commit comments

Comments
 (0)