Skip to content

Commit 8f55ff5

Browse files
authored
Merge branch 'main' into fix-kms-issues
2 parents e8d5538 + 7086030 commit 8f55ff5

146 files changed

Lines changed: 10751 additions & 334 deletions

File tree

Some content is hidden

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

‎api/src/main/java/com/cloud/agent/api/to/NicTO.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public class NicTO extends NetworkTO {
3737

3838
String networkSegmentName;
3939

40+
boolean trunkVlan;
41+
List<NetworkTO> associatedNetworks;
42+
4043
public NicTO() {
4144
super();
4245
}
@@ -163,4 +166,21 @@ public boolean isEnabled() {
163166
public void setEnabled(boolean enabled) {
164167
this.enabled = enabled;
165168
}
169+
170+
// trunkVlan/associatedNetworks carry the additional networks for a multi-VLAN trunk nic; unset for ordinary nics
171+
public boolean isTrunkVlan() {
172+
return trunkVlan;
173+
}
174+
175+
public void setTrunkVlan(boolean trunkVlan) {
176+
this.trunkVlan = trunkVlan;
177+
}
178+
179+
public List<NetworkTO> getAssociatedNetworks() {
180+
return associatedNetworks;
181+
}
182+
183+
public void setAssociatedNetworks(List<NetworkTO> associatedNetworks) {
184+
this.associatedNetworks = associatedNetworks;
185+
}
166186
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ public class EventTypes {
233233
public static final String EVENT_NIC_DETAIL_ADD = "NIC.DETAIL.ADD";
234234
public static final String EVENT_NIC_DETAIL_UPDATE = "NIC.DETAIL.UPDATE";
235235
public static final String EVENT_NIC_DETAIL_REMOVE = "NIC.DETAIL.REMOVE";
236+
public static final String EVENT_NIC_NETWORK_ASSOCIATE = "NIC.NETWORK.ASSOCIATE";
237+
public static final String EVENT_NIC_NETWORK_DISASSOCIATE = "NIC.NETWORK.DISASSOCIATE";
238+
public static final String EVENT_NIC_PRIMARY_NETWORK_CHANGE = "NIC.PRIMARY.NETWORK.CHANGE";
239+
// internal-only signal consumed by the usage job - never user-facing, not an audit event
240+
public static final String EVENT_NIC_NETWORK_ID_BACKFILL = "NIC.NETWORK.ID.BACKFILL";
236241

237242
// Load Balancers
238243
public static final String EVENT_ASSIGN_TO_LOAD_BALANCER_RULE = "LB.ASSIGN.TO.RULE";
@@ -1000,6 +1005,9 @@ public class EventTypes {
10001005

10011006
// Nic Events
10021007
entityEventDetails.put(EVENT_NIC_CREATE, Nic.class);
1008+
entityEventDetails.put(EVENT_NIC_NETWORK_ASSOCIATE, Nic.class);
1009+
entityEventDetails.put(EVENT_NIC_NETWORK_DISASSOCIATE, Nic.class);
1010+
entityEventDetails.put(EVENT_NIC_PRIMARY_NETWORK_CHANGE, Nic.class);
10031011

10041012
// Load Balancers
10051013
entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class);

‎api/src/main/java/com/cloud/host/Host.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public static String[] toStrings(Host.Type... types) {
7676
String HOST_QEMU_RBD_SUPPORT = "host.qemu.rbd.support";
7777
String HOST_SSH_PORT = "host.ssh.port";
7878
String HOST_CDROM_MAX_COUNT = "host.cdrom.max.count";
79+
String HOST_VLAN_FILTERING_ENABLED = "vlan.filtering.enabled";
80+
String HOST_VLAN_TRUNK_XML_SUPPORTED = "vlan.trunk.xml.supported";
81+
String HOST_GUEST_BRIDGE_STP_ENABLED = "guest.bridge.stp.enabled";
7982
String GUEST_OS_CATEGORY_ID = "guest.os.category.id";
8083
String GUEST_OS_RULE = "guest.os.rule";
8184
String HOST_CPU_MAX_SPEED_MHZ = "host.cpu.max.speed.mhz";

‎api/src/main/java/com/cloud/network/NetworkModel.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public interface NetworkModel {
7474
String CLOUD_DOMAIN_FILE = "cloud-domain";
7575
String CLOUD_DOMAIN_ID_FILE = "cloud-domain-id";
7676
String CLOUD_NAME_FILE = "cloud-name";
77+
String NIC_VLAN_MAPPING_FILE = "nic-vlan-mapping";
7778
int CONFIGDATA_DIR = 0;
7879
int CONFIGDATA_FILE = 1;
7980
int CONFIGDATA_CONTENT = 2;
@@ -137,6 +138,13 @@ public interface NetworkModel {
137138

138139
Nic getNicInNetwork(long vmId, long networkId);
139140

141+
/**
142+
* Resolves the nic and guest ip(s) a VM answers on for a given network - the nic's own primary network match
143+
* when one exists, or a trunk nic's association (from nic_network_map) otherwise. Returns null if the VM has
144+
* neither a primary nor an associated nic in that network.
145+
*/
146+
Pair<Nic, Network.IpAddresses> getNicAndIpInNetwork(long vmId, long networkId);
147+
140148
List<? extends Nic> getNicsForTraffic(long vmId, TrafficType type);
141149

142150
Network getDefaultNetworkForVm(long vmId);

‎api/src/main/java/com/cloud/network/NetworkService.java‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
import org.apache.cloudstack.api.command.user.network.ResetNetworkPermissionsCmd;
3636
import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
3737
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
38+
import org.apache.cloudstack.api.command.admin.network.AssociateNetworkToNicCmd;
39+
import org.apache.cloudstack.api.command.admin.network.ChangeNicPrimaryNetworkCmd;
40+
import org.apache.cloudstack.api.command.admin.network.DisassociateNetworkFromNicCmd;
3841
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
3942
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
4043
import org.apache.cloudstack.framework.config.ConfigKey;
@@ -59,6 +62,7 @@
5962
import com.cloud.utils.exception.CloudRuntimeException;
6063
import com.cloud.vm.Nic;
6164
import com.cloud.vm.NicSecondaryIp;
65+
import com.cloud.vm.VirtualMachine;
6266

6367
/**
6468
* The NetworkService interface is the "public" api to entities that make requests to the orchestration engine
@@ -249,6 +253,32 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
249253

250254
List<? extends NicSecondaryIp> listVmNicSecondaryIps(ListNicsCmd listNicsCmd);
251255

256+
/**
257+
* Associates one or more additional networks with an existing nic, delivering them as a multi-VLAN trunk
258+
*/
259+
Nic associateNetworkToNic(AssociateNetworkToNicCmd cmd)
260+
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, InsufficientAddressCapacityException;
261+
262+
/**
263+
* Disassociates a network from an existing nic, shrinking its multi-VLAN trunk. The primary network cannot be disassociated.
264+
*/
265+
Nic disassociateNetworkFromNic(DisassociateNetworkFromNicCmd cmd) throws ResourceUnavailableException;
266+
267+
/**
268+
* Changes a multi-VLAN trunk nic's primary network to one of its already-associated networks. Only allowed while
269+
* the owning Instance is stopped, since the nic is rebuilt fresh on its next start.
270+
*/
271+
Nic changeNicPrimaryNetwork(ChangeNicPrimaryNetworkCmd cmd);
272+
273+
/**
274+
* Associates additional networks with a nic that was just created (e.g. during VM deploy), before the owning
275+
* Instance has ever started. No live agent update is issued - the nic's first plug already reads these
276+
* associations fresh. requestedIps (nullable) optionally requests a specific ip4/ip6 address per associated
277+
* network id - a network with no entry (or a null map) auto-allocates, same as today.
278+
*/
279+
void associateNetworksToNic(Nic nic, List<Long> networkIds, Map<Long, IpAddresses> requestedIps)
280+
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, InsufficientAddressCapacityException;
281+
252282
AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException;
253283

254284
boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException;
@@ -281,4 +311,10 @@ Network createPrivateNetwork(String networkName, String displayText, long physic
281311
String getNicVlanValueForExternalVm(NicTO nic);
282312

283313
Long getPreferredNetworkIdForPublicIpRuleAssignment(IpAddress ip, Long networkId);
314+
315+
// Re-applies each nic's VLAN membership on the host of a Running Instance, e.g. after a memory revert recreates its taps.
316+
void reapplyLiveVlanMembership(VirtualMachine vm) throws ResourceUnavailableException;
317+
318+
// Pushes a migrated network's new VLAN and DHCP entries to the Running Instances that carry it as a trunk nic association.
319+
void refreshTrunkNicsAssociatedToNetwork(Network network);
284320
}

‎api/src/main/java/com/cloud/server/ManagementService.java‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,20 @@ public interface ManagementService {
472472

473473
Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> listHostsForMigrationOfVM(VirtualMachine vm, Long startIndex, Long pageSize, String keyword, List<VirtualMachine> vmList);
474474

475+
/**
476+
* If vm has a multi-VLAN trunk NIC and host is not ready for it (VLAN filtering not enabled), returns a
477+
* human-readable reason; null otherwise (including when vm has no such NIC, in which case host readiness
478+
* for this concern is irrelevant).
479+
*/
480+
String getMultiNetworkNicUnsuitableReason(VirtualMachine vm, Host host);
481+
482+
/**
483+
* If host's guest bridge has STP enabled, returns a human-readable caution about the forward-delay outage
484+
* every new port on it incurs (migration, nic plug, vm start); null otherwise. Applies to every VM, not
485+
* just ones with a multi-VLAN trunk NIC - unlike getMultiNetworkNicUnsuitableReason, never excludes the host.
486+
*/
487+
String getGuestBridgeStpMigrationCaution(Host host);
488+
475489
/**
476490
* Apply affinity group constraints and other exclusion rules for VM migration.
477491
* This is a helper method that can be used independently for per-iteration affinity checks in DRS.

‎api/src/main/java/com/cloud/vm/Nic.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ public enum ReservationStrategy {
146146

147147
boolean getSecondaryIp();
148148

149+
boolean getMultiNetwork();
150+
149151
//
150152
// IPv4
151153
//

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ public class ApiConstants {
335335
public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
336336
public static final String IMAGE_PATH = "imagepath";
337337
public static final String INSTANCE_CONVERSION_SUPPORTED = "instanceconversionsupported";
338+
public static final String VLAN_FILTERING_ENABLED = "vlanfilteringenabled";
339+
public static final String VLAN_TRUNK_XML_SUPPORTED = "vlantrunkxmlsupported";
338340
public static final String INTERNAL_DNS1 = "internaldns1";
339341
public static final String INTERNAL_DNS2 = "internaldns2";
340342
public static final String INTERNET_PROTOCOL = "internetprotocol";
@@ -438,6 +440,7 @@ public class ApiConstants {
438440
public static final String NIC = "nic";
439441
public static final String NICS = "nics";
440442
public static final String NIC_NETWORK_LIST = "nicnetworklist";
443+
public static final String NIC_NETWORKS_LIST = "nicnetworkslist";
441444
public static final String NIC_IP_ADDRESS_LIST = "nicipaddresslist";
442445
public static final String NIC_MULTIQUEUE_NUMBER = "nicmultiqueuenumber";
443446
public static final String NIC_PACKED_VIRTQUEUES_ENABLED = "nicpackedvirtqueuesenabled";
@@ -906,6 +909,8 @@ public class ApiConstants {
906909
public static final String ASSOCIATED_NETWORK = "associatednetwork";
907910
public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
908911
public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
912+
public static final String ASSOCIATED_NETWORKS = "associatednetworks";
913+
public static final String TRUNKED = "trunked";
909914
public static final String ASSOCIATED_VPC_ID = "associatedvpcid";
910915
public static final String ASSOCIATED_VPC_NAME = "associatedvpcname";
911916
public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";

‎api/src/main/java/org/apache/cloudstack/api/ResponseGenerator.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ UsageRecordResponse createUsageResponse(Usage usageRecord,
529529

530530
public NicResponse createNicResponse(Nic result);
531531

532+
public NicResponse createNicResponse(Nic result, Long networkId);
533+
532534
ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb,
533535
Map<Ip, UserVm> lbInstances);
534536

‎api/src/main/java/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.cloud.host.Host;
3333
import com.cloud.utils.Pair;
3434
import com.cloud.utils.Ternary;
35+
import com.cloud.vm.VirtualMachine;
3536

3637
@APICommand(name = "findHostsForMigration", description = "Find hosts suitable for migrating an Instance.", responseObject = HostForMigrationResponse.class,
3738
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -73,6 +74,8 @@ public void execute() {
7374
List<? extends Host> hostsWithCapacity = hostsForMigration.second();
7475
hostsRequiringStorageMotion = hostsForMigration.third();
7576

77+
VirtualMachine vm = _entityMgr.findById(VirtualMachine.class, getVirtualMachineId());
78+
7679
response = new ListResponse<HostForMigrationResponse>();
7780
List<HostForMigrationResponse> hostResponses = new ArrayList<HostForMigrationResponse>();
7881
for (Host host : result.first()) {
@@ -90,6 +93,11 @@ public void execute() {
9093
hostResponse.setRequiresStorageMotion(false);
9194
}
9295

96+
if (!suitableForMigration && vm != null) {
97+
hostResponse.setUnsuitableReason(_mgr.getMultiNetworkNicUnsuitableReason(vm, host));
98+
}
99+
hostResponse.setMigrationCaution(_mgr.getGuestBridgeStpMigrationCaution(host));
100+
93101
hostResponse.setObjectName("host");
94102
hostResponses.add(hostResponse);
95103
}

0 commit comments

Comments
 (0)