Skip to content

Commit 939ba82

Browse files
committed
Resolve conflicts
2 parents 39c270b + 1bff543 commit 939ba82

File tree

87 files changed

+11349
-2054
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+11349
-2054
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@
2020

2121
.pre-commit-config.yaml @jbampton
2222
/.github/linters/ @jbampton
23+
24+
/plugins/network-elements/nsx/ @Pearl1594 @nvazquez

api/src/main/java/com/cloud/configuration/ConfigurationService.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@
2424
import org.apache.cloudstack.api.ApiConstants;
2525
import org.apache.cloudstack.api.command.admin.config.ResetCfgCmd;
2626
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
27+
import org.apache.cloudstack.api.command.admin.network.CloneNetworkOfferingCmd;
2728
import org.apache.cloudstack.api.command.admin.network.CreateGuestNetworkIpv6PrefixCmd;
2829
import org.apache.cloudstack.api.command.admin.network.CreateManagementNetworkIpRangeCmd;
29-
import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
3030
import org.apache.cloudstack.api.command.admin.network.DeleteGuestNetworkIpv6PrefixCmd;
3131
import org.apache.cloudstack.api.command.admin.network.DeleteManagementNetworkIpRangeCmd;
3232
import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
3333
import org.apache.cloudstack.api.command.admin.network.ListGuestNetworkIpv6PrefixesCmd;
34+
import org.apache.cloudstack.api.command.admin.network.NetworkOfferingBaseCmd;
3435
import org.apache.cloudstack.api.command.admin.network.UpdateNetworkOfferingCmd;
3536
import org.apache.cloudstack.api.command.admin.network.UpdatePodManagementNetworkIpRangeCmd;
37+
import org.apache.cloudstack.api.command.admin.offering.CloneDiskOfferingCmd;
38+
import org.apache.cloudstack.api.command.admin.offering.CloneServiceOfferingCmd;
3639
import org.apache.cloudstack.api.command.admin.offering.CreateDiskOfferingCmd;
3740
import org.apache.cloudstack.api.command.admin.offering.CreateServiceOfferingCmd;
3841
import org.apache.cloudstack.api.command.admin.offering.DeleteDiskOfferingCmd;
@@ -105,6 +108,33 @@ public interface ConfigurationService {
105108
*/
106109
ServiceOffering createServiceOffering(CreateServiceOfferingCmd cmd);
107110

111+
/**
112+
* Clones a service offering with optional parameter overrides
113+
*
114+
* @param cmd
115+
* the command object that specifies the source offering ID and optional parameter overrides
116+
* @return the newly created service offering cloned from source, null otherwise
117+
*/
118+
ServiceOffering cloneServiceOffering(CloneServiceOfferingCmd cmd);
119+
120+
/**
121+
* Clones a disk offering with optional parameter overrides
122+
*
123+
* @param cmd
124+
* the command object that specifies the source offering ID and optional parameter overrides
125+
* @return the newly created disk offering cloned from source, null otherwise
126+
*/
127+
DiskOffering cloneDiskOffering(CloneDiskOfferingCmd cmd);
128+
129+
/**
130+
* Clones a network offering with optional parameter overrides
131+
*
132+
* @param cmd
133+
* the command object that specifies the source offering ID and optional parameter overrides
134+
* @return the newly created network offering cloned from source, null otherwise
135+
*/
136+
NetworkOffering cloneNetworkOffering(CloneNetworkOfferingCmd cmd);
137+
108138
/**
109139
* Updates a service offering
110140
*
@@ -282,7 +312,7 @@ Vlan updateVlanAndPublicIpRange(UpdateVlanIpRangeCmd cmd) throws ConcurrentOpera
282312

283313
boolean releasePublicIpRange(ReleasePublicIpRangeCmd cmd);
284314

285-
NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd);
315+
NetworkOffering createNetworkOffering(NetworkOfferingBaseCmd cmd);
286316

287317
NetworkOffering updateNetworkOffering(UpdateNetworkOfferingCmd cmd);
288318

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,13 @@ public class EventTypes {
375375

376376
// Service Offerings
377377
public static final String EVENT_SERVICE_OFFERING_CREATE = "SERVICE.OFFERING.CREATE";
378+
public static final String EVENT_SERVICE_OFFERING_CLONE = "SERVICE.OFFERING.CLONE";
378379
public static final String EVENT_SERVICE_OFFERING_EDIT = "SERVICE.OFFERING.EDIT";
379380
public static final String EVENT_SERVICE_OFFERING_DELETE = "SERVICE.OFFERING.DELETE";
380381

381382
// Disk Offerings
382383
public static final String EVENT_DISK_OFFERING_CREATE = "DISK.OFFERING.CREATE";
384+
public static final String EVENT_DISK_OFFERING_CLONE = "DISK.OFFERING.CLONE";
383385
public static final String EVENT_DISK_OFFERING_EDIT = "DISK.OFFERING.EDIT";
384386
public static final String EVENT_DISK_OFFERING_DELETE = "DISK.OFFERING.DELETE";
385387

@@ -400,6 +402,7 @@ public class EventTypes {
400402

401403
// Network offerings
402404
public static final String EVENT_NETWORK_OFFERING_CREATE = "NETWORK.OFFERING.CREATE";
405+
public static final String EVENT_NETWORK_OFFERING_CLONE = "NETWORK.OFFERING.CLONE";
403406
public static final String EVENT_NETWORK_OFFERING_ASSIGN = "NETWORK.OFFERING.ASSIGN";
404407
public static final String EVENT_NETWORK_OFFERING_EDIT = "NETWORK.OFFERING.EDIT";
405408
public static final String EVENT_NETWORK_OFFERING_REMOVE = "NETWORK.OFFERING.REMOVE";
@@ -599,6 +602,7 @@ public class EventTypes {
599602

600603
// VPC offerings
601604
public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE";
605+
public static final String EVENT_VPC_OFFERING_CLONE = "VPC.OFFERING.CLONE";
602606
public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE";
603607
public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE";
604608

@@ -631,6 +635,7 @@ public class EventTypes {
631635

632636
// Backup and Recovery events
633637
public static final String EVENT_VM_BACKUP_IMPORT_OFFERING = "BACKUP.IMPORT.OFFERING";
638+
public static final String EVENT_VM_BACKUP_OFFERING_CLONE = "BACKUP.OFFERING.CLONE";
634639
public static final String EVENT_VM_BACKUP_OFFERING_ASSIGN = "BACKUP.OFFERING.ASSIGN";
635640
public static final String EVENT_VM_BACKUP_OFFERING_REMOVE = "BACKUP.OFFERING.REMOVE";
636641
public static final String EVENT_VM_BACKUP_CREATE = "BACKUP.CREATE";
@@ -1046,11 +1051,13 @@ public class EventTypes {
10461051

10471052
// Service Offerings
10481053
entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class);
1054+
entityEventDetails.put(EVENT_SERVICE_OFFERING_CLONE, ServiceOffering.class);
10491055
entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class);
10501056
entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class);
10511057

10521058
// Disk Offerings
10531059
entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class);
1060+
entityEventDetails.put(EVENT_DISK_OFFERING_CLONE, DiskOffering.class);
10541061
entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class);
10551062
entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class);
10561063

@@ -1071,6 +1078,7 @@ public class EventTypes {
10711078

10721079
// Network offerings
10731080
entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class);
1081+
entityEventDetails.put(EVENT_NETWORK_OFFERING_CLONE, NetworkOffering.class);
10741082
entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class);
10751083
entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class);
10761084
entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class);

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,

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException
527527
* @param userId user ID
528528
* @param serviceOffering service offering for the imported VM
529529
* @param sshPublicKey ssh key for the imported VM
530+
* @param guestOsId guest OS ID for the imported VM (if not passed, then the guest OS of the template will be used)
530531
* @param hostName the name for the imported VM
531532
* @param hypervisorType hypervisor type for the imported VM
532533
* @param customParameters details for the imported VM
@@ -536,7 +537,7 @@ UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException
536537
* @throws InsufficientCapacityException in case of errors
537538
*/
538539
UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemplate template, final String instanceNameInternal, final String displayName, final Account owner, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
539-
final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey,
540+
final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey, final Long guestOsId,
540541
final String hostName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
541542
final VirtualMachine.PowerState powerState, final LinkedHashMap<String, List<NicProfile>> networkNicMap) throws InsufficientCapacityException;
542543

api/src/main/java/com/cloud/vm/VirtualMachine.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ public static StateMachine2<State, VirtualMachine.Event, VirtualMachine> getStat
124124
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping, null));
125125
s_fsm.addTransition(new Transition<State, Event>(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped, Arrays.asList(new Impact[]{Impact.USAGE})));
126126
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging,null));
127+
// Note: In addition to the Stopped -> Error transition for failed VM creation,
128+
// a VM can also transition from Expunging to Error on OperationFailedToError.
129+
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.OperationFailedToError, State.Error, null));
127130
s_fsm.addTransition(new Transition<State, Event>(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging,null));
128131
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging, null));
129132
s_fsm.addTransition(new Transition<State, Event>(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging, null));

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ public class ApiConstants {
559559
public static final String USE_STORAGE_REPLICATION = "usestoragereplication";
560560

561561
public static final String SOURCE_CIDR_LIST = "sourcecidrlist";
562+
public static final String SOURCE_OFFERING_ID = "sourceofferingid";
562563
public static final String SOURCE_ZONE_ID = "sourcezoneid";
563564
public static final String SSL_VERIFICATION = "sslverification";
564565
public static final String START_ASN = "startasn";
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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 javax.inject.Inject;
20+
21+
import org.apache.cloudstack.acl.RoleType;
22+
import org.apache.cloudstack.api.APICommand;
23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
25+
import org.apache.cloudstack.api.BaseAsyncCmd;
26+
import org.apache.cloudstack.api.BaseCmd;
27+
import org.apache.cloudstack.api.Parameter;
28+
import org.apache.cloudstack.api.ServerApiException;
29+
import org.apache.cloudstack.api.command.offering.DomainAndZoneIdResolver;
30+
import org.apache.cloudstack.api.response.BackupOfferingResponse;
31+
import org.apache.cloudstack.api.response.ZoneResponse;
32+
import org.apache.cloudstack.backup.BackupManager;
33+
import org.apache.cloudstack.backup.BackupOffering;
34+
import org.apache.cloudstack.context.CallContext;
35+
36+
import com.cloud.event.EventTypes;
37+
import com.cloud.exception.ConcurrentOperationException;
38+
import com.cloud.exception.InsufficientCapacityException;
39+
import com.cloud.exception.InvalidParameterValueException;
40+
import com.cloud.exception.NetworkRuleConflictException;
41+
import com.cloud.exception.ResourceAllocationException;
42+
import com.cloud.exception.ResourceUnavailableException;
43+
import com.cloud.utils.exception.CloudRuntimeException;
44+
45+
import java.util.Arrays;
46+
import java.util.List;
47+
import java.util.function.LongFunction;
48+
49+
@APICommand(name = "cloneBackupOffering",
50+
description = "Clones a backup offering from an existing offering",
51+
responseObject = BackupOfferingResponse.class, since = "4.23.0",
52+
authorized = {RoleType.Admin})
53+
public class CloneBackupOfferingCmd extends BaseAsyncCmd implements DomainAndZoneIdResolver {
54+
55+
@Inject
56+
protected BackupManager backupManager;
57+
58+
/////////////////////////////////////////////////////
59+
//////////////// API parameters /////////////////////
60+
////////////////////////////////////////////////////
61+
62+
@Parameter(name = ApiConstants.SOURCE_OFFERING_ID, type = BaseCmd.CommandType.UUID, entityType = BackupOfferingResponse.class,
63+
required = true, description = "The ID of the source backup offering to clone from")
64+
private Long sourceOfferingId;
65+
66+
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
67+
description = "The name of the cloned offering")
68+
private String name;
69+
70+
@Parameter(name = ApiConstants.DESCRIPTION, type = BaseCmd.CommandType.STRING, required = false,
71+
description = "The description of the cloned offering")
72+
private String description;
73+
74+
@Parameter(name = ApiConstants.EXTERNAL_ID, type = BaseCmd.CommandType.STRING, required = false,
75+
description = "The backup offering ID (from backup provider side)")
76+
private String externalId;
77+
78+
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
79+
description = "The zone ID", required = false)
80+
private Long zoneId;
81+
82+
@Parameter(name = ApiConstants.DOMAIN_ID,
83+
type = CommandType.STRING,
84+
description = "the ID of the containing domain(s) as comma separated string, public for public offerings",
85+
length = 4096)
86+
private String domainIds;
87+
88+
@Parameter(name = ApiConstants.ALLOW_USER_DRIVEN_BACKUPS, type = BaseCmd.CommandType.BOOLEAN,
89+
description = "Whether users are allowed to create adhoc backups and backup schedules", required = false)
90+
private Boolean userDrivenBackups;
91+
92+
/////////////////////////////////////////////////////
93+
/////////////////// Accessors ///////////////////////
94+
/////////////////////////////////////////////////////
95+
96+
public Long getSourceOfferingId() {
97+
return sourceOfferingId;
98+
}
99+
100+
public String getName() {
101+
return name;
102+
}
103+
104+
public String getExternalId() {
105+
return externalId;
106+
}
107+
108+
public Long getZoneId() {
109+
return zoneId;
110+
}
111+
112+
public String getDescription() {
113+
return description;
114+
}
115+
116+
public Boolean getUserDrivenBackups() {
117+
return userDrivenBackups;
118+
}
119+
120+
public List<Long> getDomainIds() {
121+
if (domainIds != null && !domainIds.isEmpty()) {
122+
return Arrays.asList(Arrays.stream(domainIds.split(",")).map(domainId -> Long.parseLong(domainId.trim())).toArray(Long[]::new));
123+
}
124+
LongFunction<List<Long>> defaultDomainsProvider = null;
125+
if (backupManager != null) {
126+
defaultDomainsProvider = backupManager::getBackupOfferingDomains;
127+
}
128+
return resolveDomainIds(domainIds, sourceOfferingId, defaultDomainsProvider, "backup offering");
129+
}
130+
131+
/////////////////////////////////////////////////////
132+
/////////////// API Implementation///////////////////
133+
/////////////////////////////////////////////////////
134+
135+
@Override
136+
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
137+
try {
138+
BackupOffering policy = backupManager.cloneBackupOffering(this);
139+
if (policy == null) {
140+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to clone backup offering");
141+
}
142+
BackupOfferingResponse response = _responseGenerator.createBackupOfferingResponse(policy);
143+
response.setResponseName(getCommandName());
144+
setResponseObject(response);
145+
} catch (InvalidParameterValueException e) {
146+
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
147+
} catch (CloudRuntimeException e) {
148+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
149+
}
150+
}
151+
152+
@Override
153+
public long getEntityOwnerId() {
154+
return CallContext.current().getCallingAccount().getId();
155+
}
156+
157+
@Override
158+
public String getEventType() {
159+
return EventTypes.EVENT_VM_BACKUP_OFFERING_CLONE;
160+
}
161+
162+
@Override
163+
public String getEventDescription() {
164+
return "Cloning backup offering: " + name + " from source offering: " + (sourceOfferingId == null ? "" : sourceOfferingId.toString());
165+
}
166+
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
public class ImportBackupOfferingCmd extends BaseAsyncCmd {
5555

5656
@Inject
57-
private BackupManager backupManager;
57+
protected BackupManager backupManager;
5858

5959
/////////////////////////////////////////////////////
6060
//////////////// API parameters /////////////////////
@@ -86,7 +86,8 @@ public class ImportBackupOfferingCmd extends BaseAsyncCmd {
8686
type = CommandType.LIST,
8787
collectionType = CommandType.UUID,
8888
entityType = DomainResponse.class,
89-
description = "the ID of the containing domain(s), null for public offerings")
89+
description = "the ID of the containing domain(s), null for public offerings",
90+
since = "4.23.0")
9091
private List<Long> domainIds;
9192

9293
/////////////////////////////////////////////////////

0 commit comments

Comments
 (0)