Skip to content

Commit 7786499

Browse files
Sigert Goeminnefmaximus
authored andcommitted
CLOUDSTACK-9776: extra DHCP options support for Nuage VSP
Co-Authored-By: Frank Maximus <frank.maximus@nuagenetworks.net> Co-Authored-By: Prashanth Manthena <prashanth.manthena@nuagenetworks.net> Co-Authored-By: Raf Smeets <raf.smeets@nuagenetworks.net> Bug: https://issues.apache.org/jira/browse/CLOUDSTACK-9776 Design-Doc: https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+extra+DHCP+option+support
1 parent 421f107 commit 7786499

41 files changed

Lines changed: 3145 additions & 70 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/com/cloud/network/Network.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static class Service {
4747
private static List<Service> supportedServices = new ArrayList<Service>();
4848

4949
public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes);
50-
public static final Service Dhcp = new Service("Dhcp");
50+
public static final Service Dhcp = new Service("Dhcp", Capability.ExtraDhcpOptions);
5151
public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification);
5252
public static final Service Gateway = new Service("Gateway");
5353
public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, Capability.MultipleIps, Capability.TrafficStatistics,
@@ -218,6 +218,7 @@ public static class Capability {
218218
public static final Capability RegionLevelVpc = new Capability("RegionLevelVpc");
219219
public static final Capability NoVlan = new Capability("NoVlan");
220220
public static final Capability PublicAccess = new Capability("PublicAccess");
221+
public static final Capability ExtraDhcpOptions = new Capability("ExtraDhcpOptions");
221222

222223
private final String name;
223224

api/src/com/cloud/network/element/DhcpServiceProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
// under the License.
1717
package com.cloud.network.element;
1818

19+
import java.util.Map;
20+
1921
import com.cloud.deploy.DeployDestination;
2022
import com.cloud.exception.ConcurrentOperationException;
2123
import com.cloud.exception.InsufficientCapacityException;
@@ -33,4 +35,6 @@ boolean configDhcpSupportForSubnet(Network network, NicProfile nic, VirtualMachi
3335
throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
3436

3537
boolean removeDhcpSupportForSubnet(Network network) throws ResourceUnavailableException;
38+
39+
boolean setExtraDhcpOptions(Network network, long nicId, Map<Integer, String> dhcpOptions);
3640
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 com.cloud.vm;
18+
19+
import org.apache.cloudstack.api.Identity;
20+
import org.apache.cloudstack.api.InternalIdentity;
21+
22+
public interface NicExtraDhcpOption extends InternalIdentity, Identity {
23+
24+
/**
25+
* Returns the nic id for which the DHCP option applies
26+
* @return nic id
27+
*/
28+
long getNicId();
29+
30+
/**
31+
* Returns the DHCP option code
32+
* @return
33+
*/
34+
int getCode();
35+
36+
/**
37+
* Returns the Dhcp value
38+
* @return
39+
*/
40+
String getValue();
41+
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
194194
* @param memory
195195
* @param cpuNumber
196196
* @param customId
197+
* @param dhcpOptionMap
198+
* - Maps the dhcp option code and the dhcp value to the network uuid
197199
* @return UserVm object if successful.
198200
*
199201
* @throws InsufficientCapacityException
@@ -208,7 +210,7 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
208210
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
209211
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
210212
String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
211-
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId) throws InsufficientCapacityException,
213+
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap) throws InsufficientCapacityException,
212214
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
213215

214216
/**
@@ -267,6 +269,8 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
267269
* @param memory
268270
* @param cpuNumber
269271
* @param customId
272+
* @param dhcpOptionMap
273+
* - Maps the dhcp option code and the dhcp value to the network uuid
270274
* @return UserVm object if successful.
271275
*
272276
* @throws InsufficientCapacityException
@@ -281,7 +285,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
281285
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
282286
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
283287
HTTPMethod httpmethod, String userData, String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
284-
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId) throws InsufficientCapacityException,
288+
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap) throws InsufficientCapacityException,
285289
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
286290

287291
/**
@@ -338,6 +342,8 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
338342
* @param memory
339343
* @param cpuNumber
340344
* @param customId
345+
* @param dhcpOptionMap
346+
* - Map that maps the DhcpOption code and their value on the Network uuid
341347
* @return UserVm object if successful.
342348
*
343349
* @throws InsufficientCapacityException
@@ -352,7 +358,7 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
352358
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
353359
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
354360
String sshKeyPair, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
355-
Map<String, String> customParameters, String customId)
361+
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap)
356362

357363
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
358364

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ public class ApiConstants {
8888
public static final String UTILIZATION = "utilization";
8989
public static final String DRIVER = "driver";
9090
public static final String ROOT_DISK_SIZE = "rootdisksize";
91+
public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
92+
public static final String DHCP_OPTIONS = "dhcpoptions";
93+
public static final String DHCP_PREFIX = "dhcp:";
9194
public static final String DISPLAY_NAME = "displayname";
9295
public static final String DISPLAY_NETWORK = "displaynetwork";
9396
public static final String DISPLAY_NIC = "displaynic";
@@ -111,6 +114,10 @@ public class ApiConstants {
111114
public static final String END_PORT = "endport";
112115
public static final String ENTRY_TIME = "entrytime";
113116
public static final String EXPIRES = "expires";
117+
public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
118+
public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
119+
public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
120+
public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
114121
public static final String FENCE = "fence";
115122
public static final String FETCH_LATEST = "fetchlatest";
116123
public static final String FIRSTNAME = "firstname";
@@ -242,6 +249,7 @@ public class ApiConstants {
242249
public static final String SCHEDULE = "schedule";
243250
public static final String SCOPE = "scope";
244251
public static final String SECRET_KEY = "usersecretkey";
252+
public static final String SECONDARY_IP = "secondaryip";
245253
public static final String SINCE = "since";
246254
public static final String KEY = "key";
247255
public static final String SEARCH_BASE = "searchbase";
@@ -309,6 +317,7 @@ public class ApiConstants {
309317
public static final String REMOVE_VLAN = "removevlan";
310318
public static final String VLAN_ID = "vlanid";
311319
public static final String ISOLATED_PVLAN = "isolatedpvlan";
320+
public static final String ISOLATION_URI = "isolationuri";
312321
public static final String VM_AVAILABLE = "vmavailable";
313322
public static final String VM_LIMIT = "vmlimit";
314323
public static final String VM_TOTAL = "vmtotal";
@@ -410,6 +419,7 @@ public class ApiConstants {
410419
public static final String CAPACITY_IOPS = "capacityiops";
411420
public static final String NETWORK_SPEED = "networkspeed";
412421
public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
422+
public static final String BROADCAST_URI = "broadcasturi";
413423
public static final String ISOLATION_METHOD = "isolationmethod";
414424
public static final String ISOLATION_METHODS = "isolationmethods";
415425
public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
@@ -536,6 +546,8 @@ public class ApiConstants {
536546
public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
537547
public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
538548
public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
549+
public static final String NSX_LOGICAL_SWITCH = "nsxlogicalswitch";
550+
public static final String NSX_LOGICAL_SWITCH_PORT = "nsxlogicalswitchport";
539551
public static final String S3_ACCESS_KEY = "accesskey";
540552
public static final String S3_SECRET_KEY = "secretkey";
541553
public static final String S3_END_POINT = "endpoint";
@@ -665,6 +677,7 @@ public class ApiConstants {
665677
public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
666678
public static final String REGION_LEVEL_VPC = "regionlevelvpc";
667679
public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
680+
public static final String NETWORK_NAME = "networkname";
668681
public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
669682
public static final String METADATA = "metadata";
670683
public static final String PHYSICAL_SIZE = "physicalsize";

api/src/org/apache/cloudstack/api/command/user/vm/AddNicToVMCmd.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
package org.apache.cloudstack.api.command.user.vm;
1818

1919
import java.util.ArrayList;
20+
import java.util.Collection;
2021
import java.util.EnumSet;
22+
import java.util.HashMap;
23+
import java.util.Map;
2124

2225
import org.apache.log4j.Logger;
2326

@@ -39,6 +42,7 @@
3942
import com.cloud.exception.InvalidParameterValueException;
4043
import com.cloud.user.Account;
4144
import com.cloud.uservm.UserVm;
45+
import com.cloud.utils.net.Dhcp;
4246
import com.cloud.utils.net.NetUtils;
4347
import com.cloud.vm.VirtualMachine;
4448

@@ -65,6 +69,10 @@ public class AddNicToVMCmd extends BaseAsyncCmd {
6569
@Parameter(name = ApiConstants.MAC_ADDRESS, type = CommandType.STRING, description = "Mac Address for the new network")
6670
private String macaddr;
6771

72+
@Parameter(name = ApiConstants.DHCP_OPTIONS, type = CommandType.MAP, description = "DHCP options which are passed to the nic"
73+
+ " Example: dhcpoptions[0].dhcp:114=url&dhcpoptions[0].dhcp:66=www.test.com")
74+
private Map dhcpOptions;
75+
6876
/////////////////////////////////////////////////////
6977
/////////////////// Accessors ///////////////////////
7078
/////////////////////////////////////////////////////
@@ -125,6 +133,28 @@ public long getEntityOwnerId() {
125133
return vm.getAccountId();
126134
}
127135

136+
public Map<Integer, String> getDhcpOptionsMap() {
137+
Map<Integer, String> dhcpOptionsMap = new HashMap<>();
138+
if (dhcpOptions != null && !dhcpOptions.isEmpty()) {
139+
140+
Collection<Map<String, String>> paramsCollection = this.dhcpOptions.values();
141+
for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
142+
for (String key : dhcpNetworkOptions.keySet()) {
143+
if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
144+
int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
145+
dhcpOptionsMap.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
146+
} else {
147+
Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
148+
dhcpOptionsMap.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
149+
}
150+
}
151+
152+
}
153+
}
154+
155+
return dhcpOptionsMap;
156+
}
157+
128158
@Override
129159
public void execute() {
130160
CallContext.current().setEventDetails("Vm Id: " + getVmId() + " Network Id: " + getNetworkId());

api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.cloud.network.Network;
6060
import com.cloud.network.Network.IpAddresses;
6161
import com.cloud.uservm.UserVm;
62+
import com.cloud.utils.net.Dhcp;
6263
import com.cloud.utils.net.NetUtils;
6364
import com.cloud.vm.VirtualMachine;
6465

@@ -187,6 +188,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
187188
@Parameter(name = ApiConstants.DEPLOYMENT_PLANNER, type = CommandType.STRING, description = "Deployment planner to use for vm allocation. Available to ROOT admin only", since = "4.4", authorized = { RoleType.Admin })
188189
private String deploymentPlanner;
189190

191+
@Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
192+
+ " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
193+
private Map dhcpOptionsNetworkList;
194+
190195
/////////////////////////////////////////////////////
191196
/////////////////// Accessors ///////////////////////
192197
/////////////////////////////////////////////////////
@@ -407,6 +412,37 @@ public String getKeyboard() {
407412
return keyboard;
408413
}
409414

415+
public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
416+
Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
417+
if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
418+
419+
Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
420+
for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
421+
String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
422+
423+
if(networkId == null) {
424+
throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
425+
}
426+
427+
Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
428+
dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
429+
430+
for (String key : dhcpNetworkOptions.keySet()) {
431+
if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
432+
int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
433+
dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
434+
} else if (!key.equals(ApiConstants.NETWORK_ID)){
435+
Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
436+
dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
437+
}
438+
}
439+
440+
}
441+
}
442+
443+
return dhcpOptionsMap;
444+
}
445+
410446
/////////////////////////////////////////////////////
411447
/////////////// API Implementation///////////////////
412448
/////////////////////////////////////////////////////

api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.apache.cloudstack.api.command.user.vm;
1818

1919
import java.util.Collection;
20+
import java.util.HashMap;
2021
import java.util.List;
2122
import java.util.Map;
2223

@@ -40,6 +41,7 @@
4041
import com.cloud.exception.ResourceUnavailableException;
4142
import com.cloud.user.Account;
4243
import com.cloud.uservm.UserVm;
44+
import com.cloud.utils.net.Dhcp;
4345
import com.cloud.vm.VirtualMachine;
4446

4547
@APICommand(name = "updateVirtualMachine", description="Updates properties of a virtual machine. The VM has to be stopped and restarted for the " +
@@ -121,6 +123,11 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction
121123
description = "optional boolean field, which indicates if details should be cleaned up or not (if set to true, details removed for this resource, details field ignored; if false or not set, no action)")
122124
private Boolean cleanupDetails;
123125

126+
@Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
127+
+ " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
128+
private Map dhcpOptionsNetworkList;
129+
130+
124131
/////////////////////////////////////////////////////
125132
/////////////////// Accessors ///////////////////////
126133
/////////////////////////////////////////////////////
@@ -182,6 +189,37 @@ public boolean isCleanupDetails(){
182189
return cleanupDetails == null ? false : cleanupDetails.booleanValue();
183190
}
184191

192+
public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
193+
Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
194+
if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
195+
196+
Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
197+
for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
198+
String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
199+
200+
if(networkId == null) {
201+
throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
202+
}
203+
204+
Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
205+
dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
206+
207+
for (String key : dhcpNetworkOptions.keySet()) {
208+
if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
209+
int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
210+
dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
211+
} else if (!key.equals(ApiConstants.NETWORK_ID)) {
212+
Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
213+
dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
214+
}
215+
}
216+
217+
}
218+
}
219+
220+
return dhcpOptionsMap;
221+
}
222+
185223
/////////////////////////////////////////////////////
186224
/////////////// API Implementation///////////////////
187225
/////////////////////////////////////////////////////

0 commit comments

Comments
 (0)