Skip to content
Open
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 @@ -36,6 +36,7 @@ public class DhcpEntryCommand extends NetworkElementCommand {
private boolean isDefault;
boolean executeInSequence = false;
boolean remove;
Long leaseTime;

public boolean isRemove() {
return remove;
Expand Down Expand Up @@ -152,4 +153,12 @@ public boolean isDefault() {
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}

public Long getLeaseTime() {
return leaseTime;
}

public void setLeaseTime(Long leaseTime) {
this.leaseTime = leaseTime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
final DhcpEntryCommand command = (DhcpEntryCommand) cmd;

final VmDhcpConfig vmDhcpConfig = new VmDhcpConfig(command.getVmName(), command.getVmMac(), command.getVmIpAddress(), command.getVmIp6Address(), command.getDuid(), command.getDefaultDns(),
command.getDefaultRouter(), command.getStaticRoutes(), command.isDefault(), command.isRemove());
command.getDefaultRouter(), command.getStaticRoutes(), command.isDefault(), command.isRemove(), command.getLeaseTime());

return generateConfigItems(vmDhcpConfig);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class VmDhcpConfig extends ConfigBase {
private String defaultGateway;
private String staticRoutes;
private boolean defaultEntry;
private Long leaseTime;

// Indicate if the entry should be removed when set to true
private boolean remove;
Expand All @@ -39,6 +40,11 @@ public VmDhcpConfig() {

public VmDhcpConfig(String hostName, String macAddress, String ipv4Address, String ipv6Address, String ipv6Duid, String dnsAddresses, String defaultGateway,
String staticRoutes, boolean defaultEntry, boolean remove) {
this(hostName, macAddress, ipv4Address, ipv6Address, ipv6Duid, dnsAddresses, defaultGateway, staticRoutes, defaultEntry, remove, null);
}

public VmDhcpConfig(String hostName, String macAddress, String ipv4Address, String ipv6Address, String ipv6Duid, String dnsAddresses, String defaultGateway,
String staticRoutes, boolean defaultEntry, boolean remove, Long leaseTime) {
super(VM_DHCP);
this.hostName = hostName;
this.macAddress = macAddress;
Expand All @@ -50,6 +56,7 @@ public VmDhcpConfig(String hostName, String macAddress, String ipv4Address, Stri
this.staticRoutes = staticRoutes;
this.defaultEntry = defaultEntry;
this.remove = remove;
this.leaseTime = leaseTime;
}

public String getHostName() {
Expand Down Expand Up @@ -132,4 +139,12 @@ public void setDefaultEntry(boolean defaultEntry) {
this.defaultEntry = defaultEntry;
}

public Long getLeaseTime() {
return leaseTime;
}

public void setLeaseTime(Long leaseTime) {
this.leaseTime = leaseTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ public interface NetworkOrchestrationService {
ConfigKey<Integer> NetworkThrottlingRate = new ConfigKey<>("Network", Integer.class, NetworkThrottlingRateCK, "200",
"Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone);

ConfigKey<Integer> DhcpLeaseTimeout = new ConfigKey<>("Network", Integer.class, "dhcp.lease.timeout", "0",
"DHCP lease time in seconds for VMs. Use 0 for infinite lease time (default). A non-zero value sets the lease duration in seconds.",
true, ConfigKey.Scope.Zone, "0-");

ConfigKey<Boolean> PromiscuousMode = new ConfigKey<>("Advanced", Boolean.class, "network.promiscuous.mode", "false",
"Whether to allow or deny promiscuous mode on NICs for applicable network elements such as for vswitch/dvswitch portgroups.", true);

Expand Down
21 changes: 13 additions & 8 deletions scripts/network/exdhcp/dhcpd_edithosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@
# under the License.


# Usage: dhcpd_edithosts.py mac ip hostname dns gateway nextserver
# Usage: dhcpd_edithosts.py mac ip hostname dns gateway nextserver [leasetime]
import sys, os
from os.path import exists
from time import sleep
from os import remove

usage = '''dhcpd_edithosts.py mac ip hostname dns gateway nextserver'''
usage = '''dhcpd_edithosts.py mac ip hostname dns gateway nextserver [leasetime]'''
conf_path = "/etc/dhcpd.conf"
file_lock = "/etc/dhcpd.conf_locked"
sleep_max = 20
host_entry = 'host %s { hardware ethernet %s; fixed-address %s; option domain-name-servers %s; option domain-name "%s"; option routers %s; default-lease-time infinite; max-lease-time infinite; min-lease-time infinite; filename "pxelinux.0";}'
host_entry1 = 'host %s { hardware ethernet %s; fixed-address %s; option domain-name-servers %s; option domain-name "%s"; option routers %s; default-lease-time infinite; max-lease-time infinite; min-lease-time infinite; next-server %s; filename "pxelinux.0";}'
host_entry = 'host %s { hardware ethernet %s; fixed-address %s; option domain-name-servers %s; option domain-name "%s"; option routers %s; default-lease-time %s; max-lease-time %s; min-lease-time %s; filename "pxelinux.0";}'
host_entry1 = 'host %s { hardware ethernet %s; fixed-address %s; option domain-name-servers %s; option domain-name "%s"; option routers %s; default-lease-time %s; max-lease-time %s; min-lease-time %s; next-server %s; filename "pxelinux.0";}'
def lock():
if exists(file_lock):
count = 0
Expand Down Expand Up @@ -59,10 +59,14 @@ def unlock():
print "Cannot remove file lock at %s" % file_lock
return False

def insert_host_entry(mac, ip, hostname, dns, gateway, next_server):
def insert_host_entry(mac, ip, hostname, dns, gateway, next_server, lease_time="infinite"):
if lock() == False:
return 1

# Convert 0 to 'infinite' for lease time
if lease_time == "0":
lease_time = "infinite"

cmd = 'sed -i /"fixed-address %s"/d %s' % (ip, conf_path)
ret = os.system(cmd)
if ret != 0:
Expand All @@ -78,9 +82,9 @@ def insert_host_entry(mac, ip, hostname, dns, gateway, next_server):
return 1

if next_server != "null":
entry = host_entry1 % (hostname, mac, ip, dns, "cloudnine.internal", gateway, next_server)
entry = host_entry1 % (hostname, mac, ip, dns, "cloudnine.internal", gateway, lease_time, lease_time, lease_time, next_server)
else:
entry = host_entry % (hostname, mac, ip, dns, "cloudnine.internal", gateway)
entry = host_entry % (hostname, mac, ip, dns, "cloudnine.internal", gateway, lease_time, lease_time, lease_time)
cmd = '''echo '%s' >> %s''' % (entry, conf_path)
ret = os.system(cmd)
if ret != 0:
Expand Down Expand Up @@ -111,12 +115,13 @@ def insert_host_entry(mac, ip, hostname, dns, gateway, next_server):
dns = sys.argv[4]
gateway = sys.argv[5]
next_server = sys.argv[6]
lease_time = sys.argv[7] if len(sys.argv) > 7 else "infinite"

if exists(conf_path) == False:
conf_path = "/etc/dhcp/dhcpd.conf"
if exists(conf_path) == False:
print "Cannot find dhcpd.conf"
sys.exit(1)

ret = insert_host_entry(mac, ip, hostname, dns, gateway, next_server)
ret = insert_host_entry(mac, ip, hostname, dns, gateway, next_server, lease_time)
sys.exit(ret)
9 changes: 8 additions & 1 deletion scripts/network/exdhcp/dnsmasq_edithosts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# $1 : the mac address
# $2 : the associated ip address
# $3 : the hostname
# $4 : the lease time (optional, defaults to 'infinite')

wait_for_dnsmasq () {
local _pid=$(pidof dnsmasq)
Expand All @@ -41,11 +42,17 @@ no_dhcp_release=$?
[ ! -f /etc/dhcphosts.txt ] && touch /etc/dhcphosts.txt
[ ! -f /var/lib/misc/dnsmasq.leases ] && touch /var/lib/misc/dnsmasq.leases

# Set lease time, default to 'infinite', convert 0 to 'infinite'
lease_time=${4:-infinite}
if [ "$lease_time" = "0" ]; then
lease_time=infinite
fi

sed -i /$1/d /etc/dhcphosts.txt
sed -i /$2,/d /etc/dhcphosts.txt
sed -i /$3,/d /etc/dhcphosts.txt

echo "$1,$2,$3,infinite" >>/etc/dhcphosts.txt
echo "$1,$2,$3,$lease_time" >>/etc/dhcphosts.txt

#release previous dhcp lease if present
if [ $no_dhcp_release -eq 0 ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ public void createDhcpEntryCommand(final VirtualRouter router, final UserVm vm,
dhcpCommand.setDefault(nic.isDefaultNic());
dhcpCommand.setRemove(remove);

// Set DHCP lease timeout from zone-scoped config (0 = infinite)
Long leaseTime = (long) NetworkOrchestrationService.DhcpLeaseTimeout.valueIn(router.getDataCenterId());
dhcpCommand.setLeaseTime(leaseTime);

dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(nic.getNetworkId(), router.getId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import com.cloud.vm.NicVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.NicDao;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.network.BgpPeerVO;
import org.apache.cloudstack.network.dao.BgpPeerDetailsDao;
import org.junit.Assert;
Expand Down Expand Up @@ -271,4 +273,52 @@ public void testCreateBgpPeersCommandsForVpc() {
Assert.assertTrue(cmd instanceof SetBgpPeersCommand);
Assert.assertEquals(4, ((SetBgpPeersCommand) cmd).getBpgPeers().length);
}

@Test
public void testDhcpLeaseTimeoutDefaultValue() {
// Test that the default value is 0 (infinite)
Integer defaultValue = NetworkOrchestrationService.DhcpLeaseTimeout.value();
Assert.assertEquals("Default DHCP lease timeout should be 0 (infinite)", 0, defaultValue.intValue());
}

@Test
public void testDhcpLeaseTimeoutAcceptsZero() {
// Test that 0 value is accepted (infinite lease)
ConfigKey<Integer> configKey = NetworkOrchestrationService.DhcpLeaseTimeout;
Assert.assertNotNull("ConfigKey should not be null", configKey);
Assert.assertEquals("ConfigKey default should be 0", "0", configKey.defaultValue());
}

@Test
public void testDhcpLeaseTimeoutAcceptsPositiveValues() {
// Test that positive values are accepted
ConfigKey<Integer> configKey = NetworkOrchestrationService.DhcpLeaseTimeout;
Assert.assertNotNull("ConfigKey should not be null", configKey);
// Verify the validator allows positive values
String validator = configKey.range();
Assert.assertNotNull("Validator should not be null", validator);
Assert.assertEquals("Validator should be '0-' (>= 0)", "0-", validator);
}

@Test
public void testDhcpLeaseTimeoutValidatorRejectsNegative() {
// Test that the validator is configured to reject negative values
ConfigKey<Integer> configKey = NetworkOrchestrationService.DhcpLeaseTimeout;
String validator = configKey.range();
Assert.assertEquals("Validator should enforce minimum of 0", "0-", validator);
}

@Test
public void testDhcpLeaseTimeoutHasZoneScope() {
// Test that the ConfigKey has Zone scope
ConfigKey<Integer> configKey = NetworkOrchestrationService.DhcpLeaseTimeout;
Assert.assertEquals("ConfigKey should have Zone scope", ConfigKey.Scope.Zone, configKey.scope());
}

@Test
public void testDhcpLeaseTimeoutIsDynamic() {
// Test that the ConfigKey is dynamic (can be updated at runtime)
ConfigKey<Integer> configKey = NetworkOrchestrationService.DhcpLeaseTimeout;
Assert.assertTrue("ConfigKey should be dynamic", configKey.isDynamic());
}
}
Loading
Loading