Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ public interface IpAddressManager {
ConfigKey<Boolean> RulesContinueOnError = new ConfigKey<Boolean>("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true",
"When true, ip address delete (ipassoc) failures are ignored", true);

ConfigKey<String> VrouterRedundantTiersPlacement = new ConfigKey<String>(
"Advanced", String.class,
"vrouter.redundant.tiers.placement",
"random",
"Set placement of vrouter ips in redundant mode in vpc tiers, this can be 3 value: `first` to use first ips in tiers, `last` to use last ips in tiers and `random` to take random ips in tiers.",
true, ConfigKey.Scope.Account);

/**
* Assigns a new public ip address.
*
Expand Down Expand Up @@ -103,6 +110,12 @@ boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean conti

String acquireGuestIpAddress(Network network, String requestedIp);

String acquireFirstGuestIpAddress(Network network);

String acquireLastGuestIpAddress(Network network);

String acquireGuestIpAddressByPlacement(Network network, String requestedIp);

boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException;

IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.cloud.network;

// 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.
public enum IpPlacement {
Random,
First,
Last;


public static IpPlacement fromString(String param) {
switch (param.trim().toLowerCase()) {
case "first":
return First;
case "last":
return Last;
}
return Random;
}
}
49 changes: 48 additions & 1 deletion server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.Collections;

import javax.inject.Inject;

Expand Down Expand Up @@ -1855,6 +1856,52 @@ public String acquireGuestIpAddress(Network network, String requestedIp) {
return NetUtils.long2Ip(array[rand.nextInt(array.length)]);
}

@Override
public String acquireFirstGuestIpAddress(Network network) {
if (_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty() && network.getCidr() == null) {
return null;
}
Set<Long> availableIps = _networkModel.getAvailableIps(network, null);
if (availableIps == null || availableIps.isEmpty()) {
s_logger.debug("There are no free ips in the network " + network);
return null;
}
return NetUtils.long2Ip(availableIps.iterator().next());
}

@Override
public String acquireLastGuestIpAddress(Network network) {
if (_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty() && network.getCidr() == null) {
return null;
}
Set<Long> availableIps = _networkModel.getAvailableIps(network, null);
if (availableIps == null || availableIps.isEmpty()) {
s_logger.debug("There are no free ips in the network " + network);
return null;
}

List<Long> availableIpsReverse = new ArrayList(availableIps);
Collections.sort(availableIpsReverse, Collections.reverseOrder());

return NetUtils.long2Ip(availableIpsReverse.iterator().next());
}

@Override
public String acquireGuestIpAddressByPlacement(Network network, String requestedIp) {
if (requestedIp != null) {
return this.acquireGuestIpAddress(network, requestedIp);
}
String placementConfig = VrouterRedundantTiersPlacement.valueIn(network.getAccountId());
IpPlacement ipPlacement = IpPlacement.fromString(placementConfig);
switch (ipPlacement) {
case Last:
return this.acquireLastGuestIpAddress(network);
case First:
return this.acquireFirstGuestIpAddress(network);
}
return this.acquireGuestIpAddress(network, null);
}

/**
* Get the list of public IPs that need to be applied for a static NAT enable/disable operation.
* Manipulating only these ips prevents concurrency issues when disabling static nat at the same time.
Expand Down Expand Up @@ -2146,7 +2193,7 @@ public String getConfigComponentName() {

@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError, SystemVmPublicIpReservationModeStrictness};
return new ConfigKey<?>[] {UseSystemPublicIps, RulesContinueOnError, SystemVmPublicIpReservationModeStrictness, VrouterRedundantTiersPlacement};
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,15 @@ public NicProfile allocate(final Network network, NicProfile nic, final VirtualM

if (isGateway) {
guestIp = network.getGateway();
} else if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
guestIp = _ipAddrMgr.acquireGuestIpAddressByPlacement(network, nic.getRequestedIPv4());
} else {
guestIp = _ipAddrMgr.acquireGuestIpAddress(network, nic.getRequestedIPv4());
if (guestIp == null && network.getGuestType() != GuestType.L2 && !_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class,
dc.getId());
}
}

if (!isGateway && guestIp == null && network.getGuestType() != GuestType.L2 && !_networkModel.listNetworkOfferingServices(network.getNetworkOfferingId()).isEmpty()) {
throw new InsufficientVirtualNetworkCapacityException("Unable to acquire Guest IP" + " address for network " + network, DataCenter.class,
dc.getId());
}

nic.setIPv4Address(guestIp);
Expand Down Expand Up @@ -460,6 +463,6 @@ public String getConfigComponentName() {

@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {UseSystemGuestVlans};
return new ConfigKey<?>[]{UseSystemGuestVlans};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ public LinkedHashMap<Network, List<? extends NicProfile>> configureGuestNic(fina
final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
if (routerDeploymentDefinition.isPublicNetwork()) {
if (routerDeploymentDefinition.isRedundant()) {
gatewayNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
gatewayNic.setIPv4Address(this.acquireGuestIpAddressForVrouterRedundant(guestNetwork));
} else {
gatewayNic.setIPv4Address(guestNetwork.getGateway());
}
Expand Down Expand Up @@ -883,4 +883,8 @@ private static boolean containsOnlyNumbers(final String str, final String endCha
}
return true;
}

public String acquireGuestIpAddressForVrouterRedundant(Network network) {
return _ipAddrMgr.acquireGuestIpAddressByPlacement(network, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public NicProfile createGuestNicProfileForVpcRouter(final RouterDeploymentDefini
final NicProfile guestNic = new NicProfile();

if (vpcRouterDeploymentDefinition.isRedundant()) {
guestNic.setIPv4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null));
guestNic.setIPv4Address(this.acquireGuestIpAddressForVrouterRedundant(guestNetwork));
} else {
guestNic.setIPv4Address(guestNetwork.getGateway());
}
Expand All @@ -133,4 +133,8 @@ public NicProfile createGuestNicProfileForVpcRouter(final RouterDeploymentDefini
return guestNic;
}

public String acquireGuestIpAddressForVrouterRedundant(Network network) {
return _ipAddrMgr.acquireGuestIpAddressByPlacement(network, null);
}

}