Skip to content

Commit 67b753c

Browse files
committed
Merge pull request #1094 from nvazquez/sharedNiciraNVP
CLOUDSTACK-9074: Support shared networking in NiciraNVP PluginJIRA TICKET: https://issues.apache.org/jira/browse/CLOUDSTACK-9074 Design Document: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Support+shared+networking+in+NiciraNVP+Plugin * pr/1094: CLOUDSTACK-9074: Move sql to 4.8.0 schema CLOUDSTACK-9074: Add NetworkGuruAdditionalFunctions license Use NSX specific config values instead of zone config values Fix method call bugs when accessign non defined variables Use helper method to migrate router vm Add helper method to migrate router vms Only set L2 Gateway in NSX device if defined CLOUDSTACK-9074: Marvin tests for NSX Shared Networks Support CLOUDSTACK-9074: Drop nicira_nvp_router_map unique index on logicalrouter_uuid CLOUDSTACK-9074: API add Gateway Service Find method CLOUDSTACK-9074: Support Shared Networks in NiciraNVP Plugin CLOUDSTACK-9074: New NiciraNVP classes for FindLRouterPort and DeleteLRouterPort API methods CLOUDSTACK-9074: New NiciraNVP classes to support Shared Networks CLOUDSTACK-9074: API Changes: Add nsxLogicalSwitch and nsxLogicalSwitchPort to listNics CLOUDSTACK-9074: API Changes: Add l2gatewayserviceuuid to NVP devices Signed-off-by: Remi Bergsma <[email protected]>
2 parents 60f0065 + de23c94 commit 67b753c

File tree

50 files changed

+2118
-125
lines changed

Some content is hidden

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

50 files changed

+2118
-125
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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.network.guru;
18+
19+
import java.util.Map;
20+
21+
public interface NetworkGuruAdditionalFunctions {
22+
23+
public static final String NSX_LSWITCH_UUID = "logicalswitch";
24+
public static final String NSX_LSWITCHPORT_UUID = "logicalswitchport";
25+
26+
void finalizeNetworkDesign(long networkId, String vlanIdAsUUID);
27+
Map<String, ? extends Object> listAdditionalNicParams(String nicUuid);
28+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ public class ApiConstants {
498498
public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid";
499499
public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
500500
public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
501+
public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid";
501502
public static final String S3_ACCESS_KEY = "accesskey";
502503
public static final String S3_SECRET_KEY = "secretkey";
503504
public static final String S3_END_POINT = "endpoint";

api/src/org/apache/cloudstack/api/response/NicResponse.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ public class NicResponse extends BaseResponse {
102102
@Param(description = "Id of the vm to which the nic belongs")
103103
private String vmId;
104104

105+
@SerializedName("nsxlogicalswitch")
106+
@Param(description = "Id of the NSX Logical Switch (if NSX based), null otherwise", since="4.6.0")
107+
private String nsxLogicalSwitch;
108+
109+
@SerializedName("nsxlogicalswitchport")
110+
@Param(description = "Id of the NSX Logical Switch Port (if NSX based), null otherwise", since="4.6.0")
111+
private String nsxLogicalSwitchPort;
112+
105113
public void setVmId(String vmId) {
106114
this.vmId = vmId;
107115
}
@@ -205,4 +213,12 @@ public void setSecondaryIps(List<NicSecondaryIpResponse> ipList) {
205213
this.secondaryIps = ipList;
206214
}
207215

216+
public void setNsxLogicalSwitch(String nsxLogicalSwitch) {
217+
this.nsxLogicalSwitch = nsxLogicalSwitch;
218+
}
219+
220+
public void setNsxLogicalSwitchPort(String nsxLogicalSwitchPort) {
221+
this.nsxLogicalSwitchPort = nsxLogicalSwitchPort;
222+
}
223+
208224
}

client/WEB-INF/classes/resources/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,7 @@ label.nfs.storage=NFS Storage
942942
label.nfs=NFS
943943
label.nic.adapter.type=NIC adapter type
944944
label.nicira.controller.address=Controller Address
945+
label.nicira.l2gatewayserviceuuid=L2 Gateway Service Uuid
945946
label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid
946947
label.nicira.transportzoneuuid=Transport Zone Uuid
947948
label.brocade.vcs.address=Vcs Switch Address

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4575,7 +4575,13 @@ private Pair<JobInfo.Status, String> orchestrateStart(final VmWorkStart work) th
45754575
}
45764576
assert vm != null;
45774577

4578-
orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner()));
4578+
try{
4579+
orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner()));
4580+
}
4581+
catch (CloudRuntimeException e){
4582+
s_logger.info("Caught CloudRuntimeException, returning job failed");
4583+
return new Pair<JobInfo.Status, String>(JobInfo.Status.FAILED, null);
4584+
}
45794585
return new Pair<JobInfo.Status, String>(JobInfo.Status.SUCCEEDED, null);
45804586
}
45814587

engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
import com.cloud.network.element.StaticNatServiceProvider;
141141
import com.cloud.network.element.UserDataServiceProvider;
142142
import com.cloud.network.guru.NetworkGuru;
143+
import com.cloud.network.guru.NetworkGuruAdditionalFunctions;
143144
import com.cloud.network.lb.LoadBalancingRulesManager;
144145
import com.cloud.network.rules.FirewallManager;
145146
import com.cloud.network.rules.FirewallRule;
@@ -168,6 +169,7 @@
168169
import com.cloud.user.User;
169170
import com.cloud.user.dao.AccountDao;
170171
import com.cloud.utils.Pair;
172+
import com.cloud.utils.UuidUtils;
171173
import com.cloud.utils.component.AdapterBase;
172174
import com.cloud.utils.component.ManagerBase;
173175
import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -670,8 +672,14 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
670672
vpcId, offering.getRedundantRouter());
671673
vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
672674
vo.setStrechedL2Network(offering.getSupportsStrechedL2());
673-
networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
674-
finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId())));
675+
NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
676+
finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()));
677+
networks.add(networkPersisted);
678+
679+
if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
680+
NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
681+
functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
682+
}
675683

676684
if (domainId != null && aclType == ACLType.Domain) {
677685
_networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
@@ -1020,6 +1028,9 @@ public Pair<NetworkGuru, NetworkVO> implementNetwork(long networkId, DeployDesti
10201028
} catch (NoTransitionException e) {
10211029
s_logger.error(e.getMessage());
10221030
return null;
1031+
} catch (CloudRuntimeException e) {
1032+
s_logger.error("Caught exception: " + e.getMessage());
1033+
return null;
10231034
} finally {
10241035
if (implemented.first() == null) {
10251036
s_logger.debug("Cleaning up because we're unable to implement the network " + network);
@@ -1911,43 +1922,45 @@ public Network createGuestNetwork(long networkOfferingId, final String name, fin
19111922
throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
19121923
+ zone.getName());
19131924
}
1914-
String uri = BroadcastDomainType.fromString(vlanId).toString();
1915-
// For Isolated networks, don't allow to create network with vlan that already exists in the zone
1916-
if (ntwkOff.getGuestType() == GuestType.Isolated) {
1917-
if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
1918-
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
1919-
} else {
1920-
List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString());
1921-
//for the network that is created as part of private gateway,
1922-
//the vnet is not coming from the data center vnet table, so the list can be empty
1923-
if (!dcVnets.isEmpty()) {
1924-
DataCenterVnetVO dcVnet = dcVnets.get(0);
1925-
// Fail network creation if specified vlan is dedicated to a different account
1926-
if (dcVnet.getAccountGuestVlanMapId() != null) {
1927-
Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
1928-
AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
1929-
if (map.getAccountId() != owner.getAccountId()) {
1930-
throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
1931-
}
1932-
// Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
1933-
} else {
1934-
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
1935-
if (maps != null && !maps.isEmpty()) {
1936-
int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
1937-
int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
1938-
if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
1939-
throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
1940-
+ owner.getAccountName());
1925+
if (! UuidUtils.validateUUID(vlanId)){
1926+
String uri = BroadcastDomainType.fromString(vlanId).toString();
1927+
// For Isolated networks, don't allow to create network with vlan that already exists in the zone
1928+
if (ntwkOff.getGuestType() == GuestType.Isolated) {
1929+
if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) {
1930+
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
1931+
} else {
1932+
List<DataCenterVnetVO> dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString());
1933+
//for the network that is created as part of private gateway,
1934+
//the vnet is not coming from the data center vnet table, so the list can be empty
1935+
if (!dcVnets.isEmpty()) {
1936+
DataCenterVnetVO dcVnet = dcVnets.get(0);
1937+
// Fail network creation if specified vlan is dedicated to a different account
1938+
if (dcVnet.getAccountGuestVlanMapId() != null) {
1939+
Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId();
1940+
AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId);
1941+
if (map.getAccountId() != owner.getAccountId()) {
1942+
throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account");
1943+
}
1944+
// Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool
1945+
} else {
1946+
List<AccountGuestVlanMapVO> maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId());
1947+
if (maps != null && !maps.isEmpty()) {
1948+
int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId());
1949+
int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId());
1950+
if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) {
1951+
throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner "
1952+
+ owner.getAccountName());
1953+
}
19411954
}
19421955
}
19431956
}
19441957
}
1945-
}
1946-
} else {
1947-
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
1948-
// shared network with same Vlan ID in the zone
1949-
if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) {
1950-
throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId);
1958+
} else {
1959+
// don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or
1960+
// shared network with same Vlan ID in the zone
1961+
if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) {
1962+
throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId);
1963+
}
19511964
}
19521965
}
19531966

@@ -2038,7 +2051,14 @@ public Network doInTransaction(TransactionStatus status) {
20382051

20392052
if (vlanIdFinal != null) {
20402053
if (isolatedPvlan == null) {
2041-
URI uri = BroadcastDomainType.fromString(vlanIdFinal);
2054+
URI uri = null;
2055+
if (UuidUtils.validateUUID(vlanIdFinal)){
2056+
//Logical router's UUID provided as VLAN_ID
2057+
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
2058+
}
2059+
else {
2060+
uri = BroadcastDomainType.fromString(vlanIdFinal);
2061+
}
20422062
userNetwork.setBroadcastUri(uri);
20432063
if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) {
20442064
userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan);
@@ -2647,6 +2667,27 @@ public List<? extends Nic> listVmNics(long vmId, Long nicId, Long networkId) {
26472667
} else {
26482668
result = _nicDao.listByVmIdAndNicIdAndNtwkId(vmId, nicId, networkId);
26492669
}
2670+
2671+
for (NicVO nic : result) {
2672+
if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) {
2673+
//For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result
2674+
s_logger.info("Listing NSX logical switch and logical switch por for each nic");
2675+
NetworkVO network = _networksDao.findById(nic.getNetworkId());
2676+
NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName());
2677+
NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru;
2678+
2679+
Map<String, ? extends Object> nsxParams = guruFunctions.listAdditionalNicParams(nic.getUuid());
2680+
if (nsxParams != null){
2681+
String lswitchUuuid = (nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID))
2682+
? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) : null;
2683+
String lswitchPortUuuid = (nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID))
2684+
? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) : null;
2685+
nic.setNsxLogicalSwitchUuid(lswitchUuuid);
2686+
nic.setNsxLogicalSwitchPortUuid(lswitchPortUuuid);
2687+
}
2688+
}
2689+
}
2690+
26502691
return result;
26512692
}
26522693

engine/schema/src/com/cloud/network/dao/NetworkVO.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,17 @@ public class NetworkVO implements Network {
172172
@Column(name = "streched_l2")
173173
boolean strechedL2Network = false;
174174

175+
@Transient
176+
transient String vlanIdAsUUID;
177+
178+
public String getVlanIdAsUUID() {
179+
return vlanIdAsUUID;
180+
}
181+
182+
public void setVlanIdAsUUID(String vlanIdAsUUID) {
183+
this.vlanIdAsUUID = vlanIdAsUUID;
184+
}
185+
175186
public NetworkVO() {
176187
uuid = UUID.randomUUID().toString();
177188
}

engine/schema/src/com/cloud/vm/NicVO.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import javax.persistence.GenerationType;
2929
import javax.persistence.Id;
3030
import javax.persistence.Table;
31+
import javax.persistence.Transient;
3132

3233
import com.cloud.network.Networks.AddressFormat;
3334
import com.cloud.network.Networks.Mode;
@@ -123,6 +124,12 @@ protected NicVO() {
123124
@Column(name = "secondary_ip")
124125
boolean secondaryIp;
125126

127+
@Transient
128+
transient String nsxLogicalSwitchUuid;
129+
130+
@Transient
131+
transient String nsxLogicalSwitchPortUuid;
132+
126133
public NicVO(String reserver, Long instanceId, long configurationId, VirtualMachine.Type vmType) {
127134
this.reserver = reserver;
128135
this.instanceId = instanceId;
@@ -371,4 +378,20 @@ public void setSecondaryIp(boolean secondaryIp) {
371378
public void setVmType(VirtualMachine.Type vmType) {
372379
this.vmType = vmType;
373380
}
381+
382+
public String getNsxLogicalSwitchUuid() {
383+
return nsxLogicalSwitchUuid;
384+
}
385+
386+
public void setNsxLogicalSwitchUuid(String nsxLogicalSwitchUuid) {
387+
this.nsxLogicalSwitchUuid = nsxLogicalSwitchUuid;
388+
}
389+
390+
public String getNsxLogicalSwitchPortUuid() {
391+
return nsxLogicalSwitchPortUuid;
392+
}
393+
394+
public void setNsxLogicalSwitchPortUuid(String nsxLogicalSwitchPortUuid) {
395+
this.nsxLogicalSwitchPortUuid = nsxLogicalSwitchPortUuid;
396+
}
374397
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.agent.api;
21+
22+
public class ConfigureSharedNetworkUuidAnswer extends Answer {
23+
24+
public ConfigureSharedNetworkUuidAnswer(final Command command, final boolean success, final String details) {
25+
super(command, success, details);
26+
}
27+
28+
public ConfigureSharedNetworkUuidAnswer(final Command command, final Exception e) {
29+
super(command, e);
30+
}
31+
32+
}

0 commit comments

Comments
 (0)