Skip to content

Commit 85babbb

Browse files
author
Sigert Goeminne
committed
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 50ffbe9 commit 85babbb

45 files changed

Lines changed: 3216 additions & 106 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, String nicUuid, 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: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ public class ApiConstants {
7979
public static final String DISK_SIZE = "disksize";
8080
public static final String DRIVER = "driver";
8181
public static final String ROOT_DISK_SIZE = "rootdisksize";
82+
public static final String DHCP_OPTIONS_NETWORK_LIST = "dhcpoptionsnetworklist";
83+
public static final String DHCP_OPTIONS = "dhcpoptions";
84+
public static final String DHCP_PREFIX = "dhcp:";
8285
public static final String DISPLAY_NAME = "displayname";
8386
public static final String DISPLAY_NETWORK = "displaynetwork";
8487
public static final String DISPLAY_NIC = "displaynic";
@@ -101,6 +104,10 @@ public class ApiConstants {
101104
public static final String END_PORT = "endport";
102105
public static final String ENTRY_TIME = "entrytime";
103106
public static final String EXPIRES = "expires";
107+
public static final String EXTRA_DHCP_OPTION = "extradhcpoption";
108+
public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
109+
public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
110+
public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
104111
public static final String FETCH_LATEST = "fetchlatest";
105112
public static final String FIRSTNAME = "firstname";
106113
public static final String FORCED = "forced";
@@ -224,6 +231,7 @@ public class ApiConstants {
224231
public static final String SCHEDULE = "schedule";
225232
public static final String SCOPE = "scope";
226233
public static final String SECRET_KEY = "usersecretkey";
234+
public static final String SECONDARY_IP = "secondaryip";
227235
public static final String SINCE = "since";
228236
public static final String KEY = "key";
229237
public static final String SEARCH_BASE = "searchbase";
@@ -289,6 +297,7 @@ public class ApiConstants {
289297
public static final String REMOVE_VLAN = "removevlan";
290298
public static final String VLAN_ID = "vlanid";
291299
public static final String ISOLATED_PVLAN = "isolatedpvlan";
300+
public static final String ISOLATION_URI = "isolationuri";
292301
public static final String VM_AVAILABLE = "vmavailable";
293302
public static final String VM_LIMIT = "vmlimit";
294303
public static final String VM_TOTAL = "vmtotal";
@@ -389,6 +398,7 @@ public class ApiConstants {
389398
public static final String CAPACITY_IOPS = "capacityiops";
390399
public static final String NETWORK_SPEED = "networkspeed";
391400
public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
401+
public static final String BROADCAST_URI = "broadcasturi";
392402
public static final String ISOLATION_METHOD = "isolationmethod";
393403
public static final String ISOLATION_METHODS = "isolationmethods";
394404
public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
@@ -515,6 +525,9 @@ public class ApiConstants {
515525
public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
516526
public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
517527
public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
528+
public static final String NSX_LOGICAL_SWITCH = "nsxlogicalswitch";
529+
public static final String NSX_LOGICAL_SWITCH_PORT = "nsxlogicalswitchport";
530+
public static final String MAC_ADDRESS = "macaddress";
518531
public static final String S3_ACCESS_KEY = "accesskey";
519532
public static final String S3_SECRET_KEY = "secretkey";
520533
public static final String S3_END_POINT = "endpoint";
@@ -644,6 +657,7 @@ public class ApiConstants {
644657
public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess";
645658
public static final String REGION_LEVEL_VPC = "regionlevelvpc";
646659
public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
660+
public static final String NETWORK_NAME = "networkname";
647661
public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
648662
public static final String METADATA = "metadata";
649663
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

@@ -38,6 +41,7 @@
3841
import com.cloud.event.EventTypes;
3942
import com.cloud.user.Account;
4043
import com.cloud.uservm.UserVm;
44+
import com.cloud.utils.net.Dhcp;
4145
import com.cloud.vm.VirtualMachine;
4246

4347
@APICommand(name = "addNicToVirtualMachine", description = "Adds VM to specified network by creating a NIC", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
@@ -60,6 +64,10 @@ public class AddNicToVMCmd extends BaseAsyncCmd {
6064
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, description = "IP Address for the new network")
6165
private String ipaddr;
6266

67+
@Parameter(name = ApiConstants.DHCP_OPTIONS, type = CommandType.MAP, description = "DHCP options which are passed to the nic"
68+
+ " Example: dhcpoptions[0].dhcp:114=url&dhcpoptions[0].dhcp:66=www.test.com")
69+
private Map dhcpOptions;
70+
6371
/////////////////////////////////////////////////////
6472
/////////////////// Accessors ///////////////////////
6573
/////////////////////////////////////////////////////
@@ -108,6 +116,28 @@ public long getEntityOwnerId() {
108116
return vm.getAccountId();
109117
}
110118

119+
public Map<Integer, String> getDhcpOptionsMap() {
120+
Map<Integer, String> dhcpOptionsMap = new HashMap<>();
121+
if (dhcpOptions != null && !dhcpOptions.isEmpty()) {
122+
123+
Collection<Map<String, String>> paramsCollection = this.dhcpOptions.values();
124+
for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
125+
for (String key : dhcpNetworkOptions.keySet()) {
126+
if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
127+
int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
128+
dhcpOptionsMap.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
129+
} else {
130+
Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
131+
dhcpOptionsMap.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
132+
}
133+
}
134+
135+
}
136+
}
137+
138+
return dhcpOptionsMap;
139+
}
140+
111141
@Override
112142
public void execute() {
113143
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

@@ -184,6 +185,10 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
184185
@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 })
185186
private String deploymentPlanner;
186187

188+
@Parameter(name = ApiConstants.DHCP_OPTIONS_NETWORK_LIST, type = CommandType.MAP, description = "DHCP options which are passed to the VM on start up"
189+
+ " Example: dhcpoptionsnetworklist[0].dhcp:114=url&dhcpoptionsetworklist[0].networkid=networkid&dhcpoptionsetworklist[0].dhcp:66=www.test.com")
190+
private Map dhcpOptionsNetworkList;
191+
187192
/////////////////////////////////////////////////////
188193
/////////////////// Accessors ///////////////////////
189194
/////////////////////////////////////////////////////
@@ -382,6 +387,37 @@ public String getKeyboard() {
382387
return keyboard;
383388
}
384389

390+
public Map<String, Map<Integer, String>> getDhcpOptionsMap() {
391+
Map<String, Map<Integer, String>> dhcpOptionsMap = new HashMap<>();
392+
if (dhcpOptionsNetworkList != null && !dhcpOptionsNetworkList.isEmpty()) {
393+
394+
Collection<Map<String, String>> paramsCollection = this.dhcpOptionsNetworkList.values();
395+
for(Map<String, String> dhcpNetworkOptions : paramsCollection) {
396+
String networkId = dhcpNetworkOptions.get(ApiConstants.NETWORK_ID);
397+
398+
if(networkId == null) {
399+
throw new IllegalArgumentException("No networkid specified when providing extra dhcp options.");
400+
}
401+
402+
Map<Integer, String> dhcpOptionsForNetwork = new HashMap<>();
403+
dhcpOptionsMap.put(networkId, dhcpOptionsForNetwork);
404+
405+
for (String key : dhcpNetworkOptions.keySet()) {
406+
if (key.startsWith(ApiConstants.DHCP_PREFIX)) {
407+
int dhcpOptionValue = Integer.parseInt(key.replaceFirst(ApiConstants.DHCP_PREFIX, ""));
408+
dhcpOptionsForNetwork.put(dhcpOptionValue, dhcpNetworkOptions.get(key));
409+
} else if (!key.equals(ApiConstants.NETWORK_ID)){
410+
Dhcp.DhcpOptionCode dhcpOptionEnum = Dhcp.DhcpOptionCode.valueOfString(key);
411+
dhcpOptionsForNetwork.put(dhcpOptionEnum.getCode(), dhcpNetworkOptions.get(key));
412+
}
413+
}
414+
415+
}
416+
}
417+
418+
return dhcpOptionsMap;
419+
}
420+
385421
/////////////////////////////////////////////////////
386422
/////////////// API Implementation///////////////////
387423
/////////////////////////////////////////////////////

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)