CLOUDSTACK-9402 : Support for underlay features (Source & Static NAT to underlay) in Nuage VSP plugin

CLOUDSTACK-9402 : Marvin tests for Source NAT and Static NAT features verification with NuageVsp (both overlay and underlay infra).

Co-Authored-By: Prashanth Manthena <prashanth.manthena@nuagenetworks.net>, Frank Maximus <frank.maximus@nuagenetworks.net>
This commit is contained in:
Nick Livens 2016-06-15 11:04:21 +02:00 committed by Prashanth Manthena
parent 027409d9bc
commit 8d4dc81223
31 changed files with 4539 additions and 168 deletions

View File

@ -237,6 +237,8 @@ public interface ResponseGenerator {
VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan);
VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan);
IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddress);
GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result);

View File

@ -399,7 +399,7 @@ public class Request {
try {
_cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class);
} catch (RuntimeException e) {
s_logger.error("Unable to convert to json: " + _content);
s_logger.error("Unable to deserialize from json: " + _content);
throw e;
}
}

View File

@ -325,6 +325,7 @@
<bean id="networkOfferingDetailsDaoImpl" class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />
<bean id="serviceOfferingDetailsDaoImpl" class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"/>
<bean id="networkDetailsDaoImpl" class="com.cloud.network.dao.NetworkDetailsDaoImpl" />
<bean id="vlanDetailsDaoImpl" class="com.cloud.dc.dao.VlanDetailsDaoImpl" />
<bean id="hostGpuGroupsDaoImpl" class="com.cloud.gpu.dao.HostGpuGroupsDaoImpl" />
<bean id="vGPUTypesDaoImpl" class="com.cloud.gpu.dao.VGPUTypesDaoImpl" />
<bean id="AffinityGroupDaoImpl" class="org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl" />

View File

@ -0,0 +1,83 @@
// 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.
package com.cloud.dc;
import org.apache.cloudstack.api.ResourceDetail;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "vlan_details")
public class VlanDetailsVO implements ResourceDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "vlan_id")
private long resourceId;
@Column(name = "name")
private String name;
@Column(name = "value", length = 1024)
private String value;
@Column(name = "display")
private boolean display = true;
public VlanDetailsVO() {
}
public VlanDetailsVO(long networkId, String name, String value, boolean display) {
this.resourceId = networkId;
this.name = name;
this.value = value;
this.display = display;
}
@Override
public long getId() {
return id;
}
@Override
public String getName() {
return name;
}
@Override
public String getValue() {
return value;
}
@Override
public long getResourceId() {
return resourceId;
}
@Override
public boolean isDisplay() {
return display;
}
}

View File

@ -0,0 +1,25 @@
// 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
// 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.
package com.cloud.dc.dao;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
public interface VlanDetailsDao extends GenericDao<VlanDetailsVO, Long>, ResourceDetailsDao<VlanDetailsVO> {
}

View File

@ -0,0 +1,32 @@
// 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
// 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.
package com.cloud.dc.dao;
import com.cloud.dc.VlanDetailsVO;
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
import org.springframework.stereotype.Component;
@Component
public class VlanDetailsDaoImpl extends ResourceDetailsDaoBase<VlanDetailsVO> implements VlanDetailsDao {
@Override
public void addDetail(long resourceId, String key, String value, boolean display) {
super.addDetail(new VlanDetailsVO(resourceId, key, value, display));
}
}

View File

@ -31,6 +31,8 @@ import com.cloud.utils.db.GenericDao;
public interface NetworkOfferingServiceMapDao extends GenericDao<NetworkOfferingServiceMapVO, Long> {
boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services);
boolean canProviderSupportServiceInNetworkOffering(long networkOfferingId, Service service, Provider provider);
List<NetworkOfferingServiceMapVO> listByNetworkOfferingId(long networkOfferingId);
void deleteByOfferingId(long networkOfferingId);

View File

@ -103,6 +103,15 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase<NetworkOffe
return false;
}
@Override
public boolean canProviderSupportServiceInNetworkOffering(long networkOfferingId, Service service, Provider provider) {
SearchCriteria<NetworkOfferingServiceMapVO> sc = AllFieldsSearch.create();
sc.setParameters("networkOfferingId", networkOfferingId);
sc.setParameters("service", service.getName());
sc.setParameters("provider", provider.getName());
return findOneBy(sc) != null;
}
@Override
public List<NetworkOfferingServiceMapVO> listByNetworkOfferingId(long networkOfferingId) {
SearchCriteria<NetworkOfferingServiceMapVO> sc = AllFieldsSearch.create();

View File

@ -0,0 +1,77 @@
//
// 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.
//
package com.cloud.agent.api.manager;
import com.cloud.agent.api.Command;
public class EntityExistsCommand<T> extends Command {
private transient Class<T> _type;
private final String _className;
private final String _uuid;
public EntityExistsCommand(Class<T> type, String uuid) {
super();
this._type = type;
this._className = type.getName();
this._uuid = uuid;
}
public Class<T> getType() {
if (_type == null) {
try {
_type = (Class<T>)Class.forName(_className);
} catch (ClassNotFoundException e) {
}
}
return _type;
}
public String getUuid() {
return _uuid;
}
@Override
public boolean executeInSequence() {
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof EntityExistsCommand)) return false;
if (!super.equals(o)) return false;
EntityExistsCommand that = (EntityExistsCommand) o;
if (getType() != null ? !getType().equals(that.getType()) : that.getType() != null) return false;
if (_uuid != null ? !_uuid.equals(that._uuid) : that._uuid != null) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (getType() != null ? getType().hashCode() : 0);
result = 31 * result + (_uuid != null ? _uuid.hashCode() : 0);
return result;
}
}

View File

@ -0,0 +1,110 @@
//
// 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.
//
package com.cloud.api.commands;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.manager.NuageVspManager;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
import org.apache.cloudstack.context.CallContext;
import javax.inject.Inject;
@APICommand(name = DisableNuageUnderlayVlanIpRangeCmd.APINAME, description = "disable Nuage underlay on vlan ip range", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.10",
authorized = {RoleType.Admin})
public class DisableNuageUnderlayVlanIpRangeCmd extends BaseAsyncCmd {
public static final String APINAME = "disableNuageUnderlayVlanIpRange";
@Inject
NuageVspManager _nuageVspManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = true, description = "VLAN IP Range ID")
private long vlanIpRangeId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public long getVlanIpRangeId() {
return vlanIpRangeId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException {
try {
boolean result = _nuageVspManager.updateNuageUnderlayVlanIpRange(vlanIpRangeId, false);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to disable underlay, VLAN IP range is already pushed to the Nuage VSP device.");
}
} catch (InvalidParameterValueException invalidParamExcp) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
} catch (CloudRuntimeException runtimeExcp) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
}
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
@Override
public String getEventType() {
return "VLAN.DISABLE.NUAGE.UNDERLAY";
}
@Override
public String getEventDescription() {
return "Disable VLAN IP range Nuage underlay";
}
}

View File

@ -0,0 +1,110 @@
//
// 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.
//
package com.cloud.api.commands;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.manager.NuageVspManager;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
import org.apache.cloudstack.context.CallContext;
import javax.inject.Inject;
@APICommand(name = EnableNuageUnderlayVlanIpRangeCmd.APINAME, description = "enable Nuage underlay on vlan ip range", responseObject = SuccessResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.10",
authorized = {RoleType.Admin})
public class EnableNuageUnderlayVlanIpRangeCmd extends BaseAsyncCmd {
public static final String APINAME = "enableNuageUnderlayVlanIpRange";
@Inject
NuageVspManager _nuageVspManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = true, description = "VLAN IP Range ID")
private long vlanIpRangeId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public long getVlanIpRangeId() {
return vlanIpRangeId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException {
try {
boolean result = _nuageVspManager.updateNuageUnderlayVlanIpRange(vlanIpRangeId, true);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable underlay, VLAN IP range is already pushed to the Nuage VSP device.");
}
} catch (InvalidParameterValueException invalidParamExcp) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage());
} catch (CloudRuntimeException runtimeExcp) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage());
}
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
@Override
public String getEventType() {
return "VLAN.ENABLE.NUAGE.UNDERLAY";
}
@Override
public String getEventDescription() {
return "Enable VLAN IP range Nuage underlay";
}
}

View File

@ -0,0 +1,80 @@
//
// 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.
//
package com.cloud.api.commands;
import com.cloud.api.response.NuageVlanIpRangeResponse;
import com.cloud.dc.Vlan;
import com.cloud.network.manager.NuageVspManager;
import com.cloud.utils.Pair;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd;
import org.apache.cloudstack.api.response.ListResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = "listNuageUnderlayVlanIpRanges", description = "enable Nuage underlay on vlan ip range", responseObject = NuageVlanIpRangeResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
since = "4.10",
authorized = {RoleType.Admin})
public class ListNuageUnderlayVlanIpRangesCmd extends ListVlanIpRangesCmd {
public static final String APINAME = "listNuageUnderlayVlanIpRanges";
@Inject
NuageVspManager _nuageVspManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = VspConstants.NUAGE_VSP_API_UNDERLAY, type = CommandType.BOOLEAN, description = "true to list only underlay enabled, false if not, empty for all")
private Boolean underlay;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Boolean getUnderlay() {
return underlay;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
Pair<List<? extends Vlan>, Integer> vlans = _mgr.searchForVlans(this);
ListResponse<NuageVlanIpRangeResponse> response = new ListResponse<NuageVlanIpRangeResponse>();
List<NuageVlanIpRangeResponse> vlanIpRanges = _nuageVspManager.filterNuageVlanIpRanges(vlans.first(), underlay);
response.setResponses(vlanIpRanges);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
}

View File

@ -33,4 +33,5 @@ public class VspConstants {
public static final String NUAGE_VSP_API_RESOURCE_FILTER = "resourcefilter";
public static final String NUAGE_VSP_API_RESOURCE_INFO = "resourceinfo";
public static final String NUAGE_VSP_CMS_ID = "cmsid";
public static final String NUAGE_VSP_API_UNDERLAY = "underlay";
}

View File

@ -0,0 +1,38 @@
//
// 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.
//
package com.cloud.api.response;
import com.cloud.api.commands.VspConstants;
import com.cloud.dc.Vlan;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
@EntityReference(value = Vlan.class)
public class NuageVlanIpRangeResponse extends VlanIpRangeResponse {
@SerializedName(VspConstants.NUAGE_VSP_API_UNDERLAY)
@Param(description = "true if Nuage underlay enabled, false if not")
private boolean underlay;
public void setUnderlay(boolean underlay) {
this.underlay = underlay;
}
}

View File

@ -53,9 +53,11 @@ import com.cloud.agent.api.element.ApplyStaticNatVspCommand;
import com.cloud.agent.api.element.ImplementVspCommand;
import com.cloud.agent.api.element.ShutDownVpcVspCommand;
import com.cloud.agent.api.element.ShutDownVspCommand;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
@ -71,7 +73,6 @@ import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks;
import com.cloud.network.NuageVspDeviceVO;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.PublicIpAddress;
@ -109,8 +110,9 @@ import com.cloud.resource.ResourceStateAdapter;
import com.cloud.resource.ServerResource;
import com.cloud.resource.UnableDeleteHostException;
import com.cloud.util.NuageVspEntityBuilder;
import com.cloud.util.NuageVspUtil;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
@ -149,6 +151,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
@Inject
VlanDao _vlanDao;
@Inject
VlanDetailsDao _vlanDetailsDao;
@Inject
NicDao _nicDao;
@Inject
VpcDao _vpcDao;
@ -282,7 +286,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
floatingIpUuids.add(ip.getUuid());
}
VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering);
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
ImplementVspCommand cmd = new ImplementVspCommand(vspNetwork, ingressFirewallRules, egressFirewallRules, floatingIpUuids, vspDhcpOptions);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
@ -353,7 +357,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO);
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false);
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
@ -399,8 +403,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
return false;
}
if ((services.contains(Service.StaticNat)) && (!services.contains(Service.SourceNat))) {
s_logger.warn("Unable to provide StaticNat without the SourceNat service.");
if (!services.contains(Service.SourceNat)) {
s_logger.warn("Unable to support services combination without SourceNat service provided by Nuage VSP.");
return false;
}
@ -438,6 +442,20 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
}
}
if (service != Service.Connectivity && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
}
return false;
}
if (service != Service.SourceNat && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
}
return false;
}
if (network.getVpcId() != null) {
NetworkOffering networkOffering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
if (!networkOffering.getIsPersistent()) {
@ -481,13 +499,15 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
for (StaticNat staticNat : rules) {
IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId());
VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId());
checkVlanUnderlayCompatibility(sourceNatVlan);
NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId());
VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(staticNat.isForRevoke(), sourceNatIp, sourceNatVlan, nicVO);
vspStaticNatDetails.add(vspStaticNat);
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config, false);
HostVO nuageVspHost = getNuageVspHost(config.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(config.getPhysicalNetworkId());
ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
@ -500,6 +520,28 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
return true;
}
private void checkVlanUnderlayCompatibility(VlanVO newVlan) throws ResourceUnavailableException {
List<VlanVO> vlans = _vlanDao.listByZone(newVlan.getDataCenterId());
if (CollectionUtils.isNotEmpty(vlans)) {
boolean newVlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, newVlan);
for (VlanVO vlan : vlans) {
if (vlan.getId() == newVlan.getId()) continue;
final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(newVlan.getVlanGateway(), newVlan.getVlanNetmask());
final String existingCidr = NetUtils.getCidrFromGatewayAndNetmask(vlan.getVlanGateway(), vlan.getVlanNetmask());
NetUtils.SupersetOrSubset supersetOrSubset = NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(newCidr, existingCidr);
if (supersetOrSubset == NetUtils.SupersetOrSubset.sameSubnet) {
boolean vlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan);
if (newVlanUnderlay != vlanUnderlay) {
throw new ResourceUnavailableException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported", Vlan.class, newVlan.getId());
}
break;
}
}
}
}
@Override
public IpDeployer getIpDeployer(Network network) {
return this;
@ -536,7 +578,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
}
});
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
VspAclRule.ACLType vspAclType = isNetworkAcl ? VspAclRule.ACLType.NetworkACL : VspAclRule.ACLType.Firewall;
ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(vspAclType, vspNetwork, vspAclRules, networkReset);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
@ -605,7 +647,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
});
Domain vpcDomain = _domainDao.findById(vpc.getDomainId());
HostVO nuageVspHost = getNuageVspHost(getPhysicalNetworkId(vpc.getZoneId()));
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(getPhysicalNetworkId(vpc.getZoneId()));
String preConfiguredDomainTemplateName;
VpcDetailVO domainTemplateNameDetail = _vpcDetailsDao.findDetail(vpc.getId(), NuageVspManager.nuageDomainTemplateDetailName);
@ -680,17 +722,4 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
}
return new DeleteHostAnswer(true);
}
private HostVO getNuageVspHost(Long physicalNetworkId) {
HostVO nuageVspHost;
List<NuageVspDeviceVO> nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId);
if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) {
NuageVspDeviceVO config = nuageVspDevices.iterator().next();
nuageVspHost = _hostDao.findById(config.getHostId());
_hostDao.loadDetails(nuageVspHost);
} else {
throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId);
}
return nuageVspHost;
}
}

View File

@ -63,7 +63,6 @@ import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks;
import com.cloud.network.NuageVspDeviceVO;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.IPAddressVO;
@ -83,7 +82,6 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.util.NuageVspEntityBuilder;
import com.cloud.utils.StringUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
@ -198,7 +196,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
HostVO nuageVspHost = getNuageVspHost(physicalNetworkId);
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering));
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
@ -256,7 +254,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
throw new IllegalStateException("The broadcast URI path " + network.getBroadcastUri() + " is empty or in an incorrect format.");
}
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false);
// Set flags for dhcp options
@ -344,7 +342,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
@Override
protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.Shared)
&& isMyIsolationMethod(physicalNetwork)) {
&& isMyIsolationMethod(physicalNetwork) && hasRequiredServices(offering)) {
if (_configMgr.isOfferingForVpc(offering) && !offering.getIsPersistent()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent");
@ -360,6 +358,23 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
}
}
private boolean hasRequiredServices(NetworkOffering networkOffering) {
if (!_ntwkOfferingSrvcDao.canProviderSupportServiceInNetworkOffering(networkOffering.getId(), Network.Service.Connectivity, Network.Provider.NuageVsp)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider");
}
return false;
}
if (!_ntwkOfferingSrvcDao.canProviderSupportServiceInNetworkOffering(networkOffering.getId(), Network.Service.SourceNat, Network.Provider.NuageVsp)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider");
}
return false;
}
return true;
}
@Override
@DB
public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) {
@ -379,7 +394,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false);
VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network);
VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic);
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(vspNetwork, vspVm, vspNic);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
@ -431,7 +446,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP");
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false);
HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId());
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
@ -447,19 +462,6 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
return super.trash(network, offering);
}
private HostVO getNuageVspHost(long physicalNetworkId) {
HostVO nuageVspHost;
List<NuageVspDeviceVO> nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId);
if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) {
NuageVspDeviceVO config = nuageVspDevices.iterator().next();
nuageVspHost = _hostDao.findById(config.getHostId());
_hostDao.loadDetails(nuageVspHost);
} else {
throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId);
}
return nuageVspHost;
}
private boolean networkHasDns(Network network) {
if (network != null) {

View File

@ -23,7 +23,10 @@ import com.cloud.api.commands.AddNuageVspDeviceCmd;
import com.cloud.api.commands.DeleteNuageVspDeviceCmd;
import com.cloud.api.commands.ListNuageVspDevicesCmd;
import com.cloud.api.commands.UpdateNuageVspDeviceCmd;
import com.cloud.api.response.NuageVlanIpRangeResponse;
import com.cloud.api.response.NuageVspDeviceResponse;
import com.cloud.dc.Vlan;
import com.cloud.host.HostVO;
import com.cloud.network.Network;
import com.cloud.network.NuageVspDeviceVO;
import com.cloud.utils.component.PluggableService;
@ -42,6 +45,8 @@ public interface NuageVspManager extends PluggableService {
static final String nuageDomainTemplateDetailName = "domainTemplateName";
static final String nuageUnderlayVlanIpRangeDetailKey = "nuage.underlay";
static final ConfigKey<Boolean> NuageVspConfigDns = new ConfigKey<Boolean>(Boolean.class, "nuagevsp.configure.dns", "Advanced", "true",
"Defines if NuageVsp plugin needs to configure DNS setting for a VM or not. True will configure the DNS and false will not configure the DNS settings", true,
Scope.Global, null);
@ -83,4 +88,10 @@ public interface NuageVspManager extends PluggableService {
List<String> getGatewaySystemIds();
HostVO getNuageVspHost(long physicalNetworkId);
boolean updateNuageUnderlayVlanIpRange(long vlanIpRangeId, boolean enabled);
List<NuageVlanIpRangeResponse> filterNuageVlanIpRanges(List<? extends Vlan> vlanIpRanges, Boolean underlay);
}

View File

@ -27,6 +27,7 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.PingNuageVspCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.manager.EntityExistsCommand;
import com.cloud.agent.api.manager.GetApiDefaultsAnswer;
import com.cloud.agent.api.manager.GetApiDefaultsCommand;
import com.cloud.agent.api.manager.SupportedApiVersionCommand;
@ -37,11 +38,20 @@ import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.commands.AddNuageVspDeviceCmd;
import com.cloud.api.commands.DeleteNuageVspDeviceCmd;
import com.cloud.api.commands.DisableNuageUnderlayVlanIpRangeCmd;
import com.cloud.api.commands.EnableNuageUnderlayVlanIpRangeCmd;
import com.cloud.api.commands.ListNuageUnderlayVlanIpRangesCmd;
import com.cloud.api.commands.ListNuageVspDevicesCmd;
import com.cloud.api.commands.UpdateNuageVspDeviceCmd;
import com.cloud.api.response.NuageVlanIpRangeResponse;
import com.cloud.api.response.NuageVspDeviceResponse;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -108,6 +118,7 @@ import com.cloud.util.NuageVspEntityBuilder;
import net.nuage.vsp.acs.NuageVspPluginClientLoader;
import net.nuage.vsp.acs.client.api.model.VspApiDefaults;
import net.nuage.vsp.acs.client.api.model.VspDomain;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@ -185,6 +196,12 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
NetworkOfferingServiceMapDao _networkOfferingServiceMapDao;
@Inject
NuageVspEntityBuilder _nuageVspEntityBuilder;
@Inject
VlanDao _vlanDao;
@Inject
VlanDetailsDao _vlanDetailsDao;
@Inject
ResponseGenerator _responseGenerator;
@Inject
MessageBus _messageBus;
@ -209,7 +226,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
@Override
public List<Class<?>> getCommands() {
return Lists.<Class<?>>newArrayList(AddNuageVspDeviceCmd.class, DeleteNuageVspDeviceCmd.class, ListNuageVspDevicesCmd.class,
UpdateNuageVspDeviceCmd.class);
UpdateNuageVspDeviceCmd.class, EnableNuageUnderlayVlanIpRangeCmd.class, DisableNuageUnderlayVlanIpRangeCmd.class, ListNuageUnderlayVlanIpRangesCmd.class);
}
@Override
@ -677,6 +694,63 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
return Lists.newArrayList();
}
@Override
public HostVO getNuageVspHost(long physicalNetworkId) {
HostVO nuageVspHost;
List<NuageVspDeviceVO> nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId);
if (CollectionUtils.isEmpty(nuageVspDevices)) {
// Perhaps another physical network is passed from within the same zone, find the VSP physical network in that case
PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
List<PhysicalNetworkVO> physicalNetworksInZone = _physicalNetworkDao.listByZone(physicalNetwork.getDataCenterId());
for (PhysicalNetworkVO physicalNetworkInZone : physicalNetworksInZone) {
if (physicalNetworkInZone.getIsolationMethods().contains(PhysicalNetwork.IsolationMethod.VSP.name())) {
nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkInZone.getId());
break;
}
}
}
if (CollectionUtils.isNotEmpty(nuageVspDevices)) {
NuageVspDeviceVO config = nuageVspDevices.iterator().next();
nuageVspHost = _hostDao.findById(config.getHostId());
_hostDao.loadDetails(nuageVspHost);
} else {
throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId);
}
return nuageVspHost;
}
@Override
public boolean updateNuageUnderlayVlanIpRange(long vlanIpRangeId, boolean enabled) {
VlanVO staticNatVlan = _vlanDao.findById(vlanIpRangeId);
HostVO nuageVspHost = getNuageVspHost(staticNatVlan.getPhysicalNetworkId());
EntityExistsCommand<Vlan> cmd = new EntityExistsCommand<Vlan>(Vlan.class, staticNatVlan.getUuid());
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer != null && !answer.getResult()) {
_vlanDetailsDao.addDetail(staticNatVlan.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey, String.valueOf(enabled), false);
return true;
}
return false;
}
@Override
public List<NuageVlanIpRangeResponse> filterNuageVlanIpRanges(List<? extends Vlan> vlanIpRanges, Boolean underlay) {
List<NuageVlanIpRangeResponse> nuageVlanIpRanges = Lists.newArrayList();
for (Vlan vlanIpRange : vlanIpRanges) {
NuageVlanIpRangeResponse nuageVlanIpRange = (NuageVlanIpRangeResponse) _responseGenerator.createVlanIpRangeResponse(NuageVlanIpRangeResponse.class, vlanIpRange);
VlanDetailsVO nuageUnderlayDetail = _vlanDetailsDao.findDetail(vlanIpRange.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey);
boolean underlayEnabled = nuageUnderlayDetail != null && nuageUnderlayDetail.getValue().equalsIgnoreCase(String.valueOf(true));
nuageVlanIpRange.setUnderlay(underlayEnabled);
if (underlay == null || underlayEnabled == underlay) {
nuageVlanIpRanges.add(nuageVlanIpRange);
}
nuageVlanIpRange.setObjectName("nuagevlaniprange");
}
return nuageVlanIpRanges;
}
@Override
public boolean preStateTransitionEvent(Status oldState, Status.Event event, Status newState, Host host, boolean status, Object opaque) {
return true;

View File

@ -58,6 +58,7 @@ import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
import com.cloud.agent.api.guru.TrashNetworkVspCommand;
import com.cloud.agent.api.guru.UpdateDhcpOptionVspCommand;
import com.cloud.agent.api.manager.EntityExistsCommand;
import com.cloud.agent.api.manager.GetApiDefaultsAnswer;
import com.cloud.agent.api.manager.GetApiDefaultsCommand;
import com.cloud.agent.api.manager.SupportedApiVersionCommand;
@ -65,12 +66,14 @@ import com.cloud.agent.api.sync.SyncDomainAnswer;
import com.cloud.agent.api.sync.SyncDomainCommand;
import com.cloud.agent.api.sync.SyncNuageVspCmsIdAnswer;
import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand;
import com.cloud.dc.Vlan;
import com.cloud.host.Host;
import com.cloud.resource.ServerResource;
import com.cloud.util.NuageVspUtil;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.exception.CloudRuntimeException;
import net.nuage.vsp.acs.client.common.model.NuageVspEntity;
import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType;
@ -323,6 +326,8 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
return executeRequest((GetApiDefaultsCommand)cmd);
} else if (cmd instanceof SupportedApiVersionCommand) {
return executeRequest((SupportedApiVersionCommand)cmd);
} else if (cmd instanceof EntityExistsCommand) {
return executeRequest((EntityExistsCommand)cmd);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received unsupported command " + cmd.toString());
@ -514,6 +519,21 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
}
}
private Answer executeRequest(EntityExistsCommand cmd) {
try {
isNuageVspApiLoaded();
NuageVspEntity entityType = null;
if (Vlan.class.isAssignableFrom(cmd.getType())) {
entityType = NuageVspEntity.SHARED_NETWORK;
}
boolean exists = _nuageVspApiClient.entityExists(entityType, cmd.getUuid());
return new Answer(cmd, exists, "Check if entity with UUID " + cmd.getUuid() + " of type " + entityType + " exists");
} catch (ExecutionException | ConfigurationException e) {
s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e);
return new Answer(cmd, e);
}
}
protected void isNuageVspApiLoaded() throws ConfigurationException {
if (!_isNuageVspClientLoaded || _nuageVspApiClient == null) {
throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE);

View File

@ -21,6 +21,7 @@ package com.cloud.util;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -88,6 +89,8 @@ public class NuageVspEntityBuilder {
@Inject
VlanDao _vlanDao;
@Inject
VlanDetailsDao _vlanDetailsDao;
@Inject
ConfigurationDao _configurationDao;
@Inject
IPAddressDao _ipAddressDao;
@ -291,7 +294,8 @@ public class NuageVspEntityBuilder {
.oneToOneNat(staticNatIp.isOneToOneNat())
.vlanUuid(staticNatVlan.getUuid())
.vlanGateway(staticNatVlan.getVlanGateway())
.vlanNetmask(staticNatVlan.getVlanNetmask());
.vlanNetmask(staticNatVlan.getVlanNetmask())
.vlanUnderlay(NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, staticNatVlan));
if (nic != null) {
VspNic vspNic = buildVspNic(nic);

View File

@ -19,6 +19,9 @@
package com.cloud.util;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.network.Network;
import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao;
@ -58,4 +61,9 @@ public class NuageVspUtil {
byte[] passwordBytes = Base64.decodeBase64(encodedPasswordBytes);
return new String(passwordBytes, StringUtils.getPreferredCharset());
}
public static boolean isUnderlayEnabledForVlan(VlanDetailsDao vlanDetailsDao, Vlan vlan) {
VlanDetailsVO nuageUnderlayDetail = vlanDetailsDao.findDetail(vlan.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey);
return nuageUnderlayDetail != null && nuageUnderlayDetail.getValue().equalsIgnoreCase(String.valueOf(true));
}
}

View File

@ -19,6 +19,17 @@
package com.cloud.agent.api;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import com.google.common.collect.Maps;
import com.google.common.testing.EqualsTester;
import com.google.gson.Gson;
import com.cloud.agent.api.element.ApplyAclRuleVspCommand;
import com.cloud.agent.api.element.ApplyStaticNatVspCommand;
import com.cloud.agent.api.element.ImplementVspCommand;
@ -27,71 +38,76 @@ import com.cloud.agent.api.guru.DeallocateVmVspCommand;
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand;
import com.cloud.agent.api.guru.TrashNetworkVspCommand;
import com.cloud.agent.api.manager.EntityExistsCommand;
import com.cloud.agent.api.manager.SupportedApiVersionCommand;
import com.cloud.agent.api.sync.SyncDomainCommand;
import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand;
import com.google.common.collect.Maps;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import com.cloud.serializer.GsonHelper;
public class CommandsTest {
private static final Gson s_gson = GsonHelper.getGson();
private EqualsTester tester = new EqualsTester();
@Test
public void testCommandEquals() throws IllegalAccessException, InvocationTargetException, InstantiationException {
ApplyAclRuleVspCommand applyAclRuleVspCommand = fillObject(ApplyAclRuleVspCommand.class);
ApplyAclRuleVspCommand otherApplyAclRuleVspCommand = fillObject(ApplyAclRuleVspCommand.class);
addCommandEqualityGroup(ApplyAclRuleVspCommand.class);
addCommandEqualityGroup(ImplementVspCommand.class);
addCommandEqualityGroup(ApplyStaticNatVspCommand.class);
addCommandEqualityGroup(ShutDownVpcVspCommand.class);
addCommandEqualityGroup(DeallocateVmVspCommand.class);
addCommandEqualityGroup(ImplementNetworkVspCommand.class);
addCommandEqualityGroup(ReserveVmInterfaceVspCommand.class);
addCommandEqualityGroup(TrashNetworkVspCommand.class);
addCommandEqualityGroup(SyncDomainCommand.class);
addCommandEqualityGroup(SyncNuageVspCmsIdCommand.class);
addCommandEqualityGroup(PingNuageVspCommand.class);
ApplyStaticNatVspCommand applyStaticNatVspCommand = fillObject(ApplyStaticNatVspCommand.class);
ApplyStaticNatVspCommand otherApplyStaticNatVspCommand = fillObject(ApplyStaticNatVspCommand.class);
SupportedApiVersionCommand supportedApiVersionCommandA = new SupportedApiVersionCommand("3.2");
SupportedApiVersionCommand supportedApiVersionCommandB = new SupportedApiVersionCommand("3.2");
ImplementVspCommand implementVspCommand = fillObject(ImplementVspCommand.class);
ImplementVspCommand otherImplementVspCommand = fillObject(ImplementVspCommand.class);
EntityExistsCommand entityExistsCommandA = new EntityExistsCommand(Command.class, "uuid");
EntityExistsCommand entityExistsCommandB = new EntityExistsCommand(Command.class, "uuid");
ShutDownVpcVspCommand shutDownVpcVspCommand = fillObject(ShutDownVpcVspCommand.class);
ShutDownVpcVspCommand otherShutDownVpcVspCommand = fillObject(ShutDownVpcVspCommand.class);
tester
.addEqualityGroup(supportedApiVersionCommandA, supportedApiVersionCommandB)
.addEqualityGroup(entityExistsCommandA, entityExistsCommandB)
.testEquals();
}
DeallocateVmVspCommand deallocateVmVspCommand = fillObject(DeallocateVmVspCommand.class);
DeallocateVmVspCommand otherDeallocateVmVspCommand = fillObject(DeallocateVmVspCommand.class);
@Test
public void testCommandGsonEquals() throws IllegalAccessException, InvocationTargetException, InstantiationException {
addCommandGsonEqualityGroup(ApplyAclRuleVspCommand.class);
addCommandGsonEqualityGroup(ImplementVspCommand.class);
addCommandGsonEqualityGroup(ApplyStaticNatVspCommand.class);
addCommandGsonEqualityGroup(ShutDownVpcVspCommand.class);
addCommandGsonEqualityGroup(DeallocateVmVspCommand.class);
addCommandGsonEqualityGroup(ImplementNetworkVspCommand.class);
addCommandGsonEqualityGroup(ReserveVmInterfaceVspCommand.class);
addCommandGsonEqualityGroup(TrashNetworkVspCommand.class);
addCommandGsonEqualityGroup(new SupportedApiVersionCommand("3.2"));
addCommandGsonEqualityGroup(SyncDomainCommand.class);
addCommandGsonEqualityGroup(SyncNuageVspCmsIdCommand.class);
addCommandGsonEqualityGroup(PingNuageVspCommand.class);
addCommandGsonEqualityGroup(new EntityExistsCommand(Command.class, "uuid"));
ImplementNetworkVspCommand implementNetworkVspCommand = fillObject(ImplementNetworkVspCommand.class);
ImplementNetworkVspCommand otherImplementNetworkVspCommand = fillObject(ImplementNetworkVspCommand.class);
tester.testEquals();
}
ReserveVmInterfaceVspCommand reserveVmInterfaceVspCommand = fillObject(ReserveVmInterfaceVspCommand.class);
ReserveVmInterfaceVspCommand otherReserveVmInterfaceVspCommand = fillObject(ReserveVmInterfaceVspCommand.class);
private <T extends Command> void addCommandGsonEqualityGroup(Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException{
addCommandGsonEqualityGroup(fillObject(clazz));
}
TrashNetworkVspCommand trashNetworkVspCommand = fillObject(TrashNetworkVspCommand.class);
TrashNetworkVspCommand otherTrashNetworkVspCommand = fillObject(TrashNetworkVspCommand.class);
private <T extends Command> void addCommandGsonEqualityGroup(Command command) throws IllegalAccessException, InvocationTargetException, InstantiationException{
Command[] forwardedCommands = s_gson.fromJson(s_gson.toJson(new Command[] { command }), Command[].class);
Assert.assertEquals(command, forwardedCommands[0]);
tester.addEqualityGroup(command, forwardedCommands[0]);
}
SupportedApiVersionCommand supportedApiVersionCommand = new SupportedApiVersionCommand("3.2");
SupportedApiVersionCommand otherSupportedApiVersionCommand = new SupportedApiVersionCommand("3.2");
SyncDomainCommand syncDomainCommand = fillObject(SyncDomainCommand.class);
SyncDomainCommand otherSyncDomainCommand = fillObject(SyncDomainCommand.class);
SyncNuageVspCmsIdCommand syncNuageVspCmsIdCommand = fillObject(SyncNuageVspCmsIdCommand.class);
SyncNuageVspCmsIdCommand otherSyncNuageVspCmsIdCommand = fillObject(SyncNuageVspCmsIdCommand.class);
PingNuageVspCommand pingNuageVspCommand = fillObject(PingNuageVspCommand.class);
PingNuageVspCommand otherPingNuageVspCommand = fillObject(PingNuageVspCommand.class);
new EqualsTester()
.addEqualityGroup(applyAclRuleVspCommand, otherApplyAclRuleVspCommand)
.addEqualityGroup(applyStaticNatVspCommand, otherApplyStaticNatVspCommand)
.addEqualityGroup(implementVspCommand, otherImplementVspCommand)
.addEqualityGroup(shutDownVpcVspCommand, otherShutDownVpcVspCommand)
.addEqualityGroup(deallocateVmVspCommand, otherDeallocateVmVspCommand)
.addEqualityGroup(implementNetworkVspCommand, otherImplementNetworkVspCommand)
.addEqualityGroup(reserveVmInterfaceVspCommand, otherReserveVmInterfaceVspCommand)
.addEqualityGroup(trashNetworkVspCommand, otherTrashNetworkVspCommand)
.addEqualityGroup(supportedApiVersionCommand, otherSupportedApiVersionCommand)
.addEqualityGroup(syncDomainCommand, otherSyncDomainCommand)
.addEqualityGroup(syncNuageVspCmsIdCommand, otherSyncNuageVspCmsIdCommand)
.addEqualityGroup(pingNuageVspCommand, otherPingNuageVspCommand)
.testEquals();
private <T extends Command> void addCommandEqualityGroup(Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {
Command a = fillObject(clazz);
Command b = fillObject(clazz);
tester.addEqualityGroup(a, b);
}
private <T> T fillObject(Class<T> clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException {

View File

@ -113,6 +113,9 @@ public class NuageVspElementTest extends NuageTest {
public void setUp() throws Exception {
super.setUp();
_nuageVspElement._nuageVspEntityBuilder = _nuageVspEntityBuilder;
when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NuageVsp)).thenReturn(true);
_nuageVspElement.configure("NuageVspTestElement", Collections.<String, Object>emptyMap());
}
@ -128,7 +131,6 @@ public class NuageVspElementTest extends NuageTest {
when(ntwkoffer.getIsPersistent()).thenReturn(true);
when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer);
when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
// Golden path
assertTrue(_nuageVspElement.canHandle(net, Service.Connectivity));
@ -162,7 +164,6 @@ public class NuageVspElementTest extends NuageTest {
when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID);
when(network.getDomainId()).thenReturn(NETWORK_ID);
when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true);
when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true);
final NetworkOffering offering = mock(NetworkOffering.class);
when(offering.getId()).thenReturn(NETWORK_ID);
@ -186,6 +187,7 @@ public class NuageVspElementTest extends NuageTest {
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress)).thenReturn(new ArrayList<FirewallRuleVO>());
when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress)).thenReturn(new ArrayList<FirewallRuleVO>());
@ -235,6 +237,7 @@ public class NuageVspElementTest extends NuageTest {
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
final Answer answer = mock(Answer.class);
@ -263,6 +266,7 @@ public class NuageVspElementTest extends NuageTest {
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
@ -292,6 +296,7 @@ public class NuageVspElementTest extends NuageTest {
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice}));
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class));
final Answer answer = mock(Answer.class);
@ -329,6 +334,7 @@ public class NuageVspElementTest extends NuageTest {
when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Lists.newArrayList(nuageVspDevice));
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
DomainRouterVO domainRouter = mock(DomainRouterVO.class);
when(domainRouter.getUuid()).thenReturn("aaaaaa");

View File

@ -144,6 +144,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(host.getId()).thenReturn(NETWORK_ID);
when(_agentManager.easySend(eq(NETWORK_ID), any(Command.class))).thenReturn(new Answer(null));
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(device));
@ -158,7 +159,8 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
when(offering.getIsPersistent()).thenReturn(false);
when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false);
when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true);
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
when(offering.getTrafficType()).thenReturn(TrafficType.Guest);
when(offering.getGuestType()).thenReturn(GuestType.Isolated);
@ -199,7 +201,8 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
when(offering.getIsPersistent()).thenReturn(false);
when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false);
when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true);
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true);
when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true);
final DeploymentPlan plan = mock(DeploymentPlan.class);
final Network network = mock(Network.class);

View File

@ -20,8 +20,10 @@
package com.cloud.util;
import com.cloud.NuageTest;
import com.cloud.dc.VlanDetailsVO;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.dc.dao.VlanDetailsDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.network.Network;
@ -58,6 +60,8 @@ import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -77,6 +81,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
private NetworkOfferingDao _networkOfferingDao = mock(NetworkOfferingDao.class);
private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao = mock(NetworkOfferingServiceMapDao.class);
private VlanDao _vlanDao = mock(VlanDao.class);
private VlanDetailsDao _vlanDetailsDao = mock(VlanDetailsDao.class);
private IPAddressDao _ipAddressDao = mock(IPAddressDao.class);
private NetworkDetailsDao _networkDetailsDao = mock(NetworkDetailsDao.class);
private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder();
@ -87,6 +92,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
private NetworkOfferingVO _mockedSharedNetworkOffering = mock(NetworkOfferingVO.class);
private NetworkOfferingVO _mockedL2NetworkOffering = mock(NetworkOfferingVO.class);
private VlanVO _mockedVlan = mock(VlanVO.class);
private VlanDetailsVO _mockedVlanDetail = mock(VlanDetailsVO.class);
private VpcVO _mockedVpc = mock(VpcVO.class);
private NetworkVO _mockedNetwork = mock(NetworkVO.class);
private NetworkVO _mockedVpcNetwork = mock(NetworkVO.class);
@ -111,6 +117,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
_nuageVspEntityBuilder._networkOfferingDao = _networkOfferingDao;
_nuageVspEntityBuilder._networkOfferingServiceMapDao = _networkOfferingServiceMapDao;
_nuageVspEntityBuilder._vlanDao = _vlanDao;
_nuageVspEntityBuilder._vlanDetailsDao = _vlanDetailsDao;
_nuageVspEntityBuilder._configurationDao = _configurationDao;
_nuageVspEntityBuilder._ipAddressDao = _ipAddressDao;
_nuageVspEntityBuilder._networkModel = _networkModel;
@ -122,6 +129,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
setUpMockedNetworkOffering(_mockedSharedNetworkOffering, Network.GuestType.Shared);
setUpMockedNetworkOffering(_mockedL2NetworkOffering, Network.GuestType.Isolated);
setUpMockedVlan();
setUpMockedVlanDetail();
setUpMockedVpc();
setUpMockedNetwork(_mockedNetwork, NETWORK_OFFERING_ID, null);
setUpMockedNetwork(_mockedVpcNetwork, NETWORK_OFFERING_ID, VPC_ID);
@ -319,6 +327,10 @@ public class NuageVspEntityBuilderTest extends NuageTest {
when(_mockedVlan.getIpRange()).thenReturn("192.168.2.2-192.168.2.200");
}
private void setUpMockedVlanDetail() {
when(_mockedVlanDetail.getValue()).thenReturn("true");
}
private void setUpMockedVpc() {
when(_mockedVpc.getUuid()).thenReturn("vpcUuid");
when(_mockedVpc.getName()).thenReturn("vpcName");
@ -406,6 +418,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
when(_networkModel.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
when(_networkModel.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true);
when(_vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Lists.newArrayList(_mockedVlan));
when(_vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(_mockedVlanDetail);
when(_vpcDao.findById(VPC_ID)).thenReturn(_mockedVpc);
when(_ipAddressDao.findById(SOURCE_IP_ADDRESS_ID)).thenReturn(_mockedStaticNatIp);
}

View File

@ -634,83 +634,92 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) {
Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId());
return createVlanIpRangeResponse(VlanIpRangeResponse.class, vlan);
}
VlanIpRangeResponse vlanResponse = new VlanIpRangeResponse();
vlanResponse.setId(vlan.getUuid());
if (vlan.getVlanType() != null) {
vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork));
}
vlanResponse.setVlan(vlan.getVlanTag());
DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId());
if (zone != null) {
vlanResponse.setZoneId(zone.getUuid());
}
@Override
public VlanIpRangeResponse createVlanIpRangeResponse(Class<? extends VlanIpRangeResponse> subClass, Vlan vlan) {
try {
Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId());
if (podId != null) {
HostPodVO pod = ApiDBUtils.findPodById(podId);
if (pod != null) {
vlanResponse.setPodId(pod.getUuid());
vlanResponse.setPodName(pod.getName());
VlanIpRangeResponse vlanResponse = subClass.newInstance();
vlanResponse.setId(vlan.getUuid());
if (vlan.getVlanType() != null) {
vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork));
}
}
vlanResponse.setGateway(vlan.getVlanGateway());
vlanResponse.setNetmask(vlan.getVlanNetmask());
// get start ip and end ip of corresponding vlan
String ipRange = vlan.getIpRange();
if (ipRange != null) {
String[] range = ipRange.split("-");
vlanResponse.setStartIp(range[0]);
vlanResponse.setEndIp(range[1]);
}
vlanResponse.setIp6Gateway(vlan.getIp6Gateway());
vlanResponse.setIp6Cidr(vlan.getIp6Cidr());
String ip6Range = vlan.getIp6Range();
if (ip6Range != null) {
String[] range = ip6Range.split("-");
vlanResponse.setStartIpv6(range[0]);
vlanResponse.setEndIpv6(range[1]);
}
if (vlan.getNetworkId() != null) {
Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId());
if (nw != null) {
vlanResponse.setNetworkId(nw.getUuid());
vlanResponse.setVlan(vlan.getVlanTag());
DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId());
if (zone != null) {
vlanResponse.setZoneId(zone.getUuid());
}
}
Account owner = ApiDBUtils.getVlanAccount(vlan.getId());
if (owner != null) {
populateAccount(vlanResponse, owner.getId());
populateDomain(vlanResponse, owner.getDomainId());
} else {
Domain domain = ApiDBUtils.getVlanDomain(vlan.getId());
if (domain != null) {
populateDomain(vlanResponse, domain.getId());
if (podId != null) {
HostPodVO pod = ApiDBUtils.findPodById(podId);
if (pod != null) {
vlanResponse.setPodId(pod.getUuid());
vlanResponse.setPodName(pod.getName());
}
}
vlanResponse.setGateway(vlan.getVlanGateway());
vlanResponse.setNetmask(vlan.getVlanNetmask());
// get start ip and end ip of corresponding vlan
String ipRange = vlan.getIpRange();
if (ipRange != null) {
String[] range = ipRange.split("-");
vlanResponse.setStartIp(range[0]);
vlanResponse.setEndIp(range[1]);
}
vlanResponse.setIp6Gateway(vlan.getIp6Gateway());
vlanResponse.setIp6Cidr(vlan.getIp6Cidr());
String ip6Range = vlan.getIp6Range();
if (ip6Range != null) {
String[] range = ip6Range.split("-");
vlanResponse.setStartIpv6(range[0]);
vlanResponse.setEndIpv6(range[1]);
}
if (vlan.getNetworkId() != null) {
Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId());
if (nw != null) {
vlanResponse.setNetworkId(nw.getUuid());
}
}
Account owner = ApiDBUtils.getVlanAccount(vlan.getId());
if (owner != null) {
populateAccount(vlanResponse, owner.getId());
populateDomain(vlanResponse, owner.getDomainId());
} else {
Long networkId = vlan.getNetworkId();
if (networkId != null) {
Network network = _ntwkModel.getNetwork(networkId);
if (network != null) {
Long accountId = network.getAccountId();
populateAccount(vlanResponse, accountId);
populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId());
Domain domain = ApiDBUtils.getVlanDomain(vlan.getId());
if (domain != null) {
populateDomain(vlanResponse, domain.getId());
} else {
Long networkId = vlan.getNetworkId();
if (networkId != null) {
Network network = _ntwkModel.getNetwork(networkId);
if (network != null) {
Long accountId = network.getAccountId();
populateAccount(vlanResponse, accountId);
populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId());
}
}
}
}
}
if (vlan.getPhysicalNetworkId() != null) {
PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
if (pnw != null) {
vlanResponse.setPhysicalNetworkId(pnw.getUuid());
if (vlan.getPhysicalNetworkId() != null) {
PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId());
if (pnw != null) {
vlanResponse.setPhysicalNetworkId(pnw.getUuid());
}
}
vlanResponse.setObjectName("vlan");
return vlanResponse;
} catch (InstantiationException | IllegalAccessException e) {
throw new CloudRuntimeException("Failed to create Vlan IP Range response", e);
}
vlanResponse.setObjectName("vlan");
return vlanResponse;
}
@Override

View File

@ -35,4 +35,14 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervi
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows 10', 257, now());
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows 10', 258, now());
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows Server 2012', 259, now());
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows Server 2012', 259, now());
CREATE TABLE `cloud`.`vlan_details` (
`id` bigint unsigned NOT NULL auto_increment,
`vlan_id` bigint unsigned NOT NULL COMMENT 'vlan id',
`name` varchar(255) NOT NULL,
`value` varchar(1024) NOT NULL,
`display` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should detail be displayed to the end user',
PRIMARY KEY (`id`),
CONSTRAINT `fk_vlan_details__vlan_id` FOREIGN KEY `fk_vlan_details__vlan_id`(`vlan_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -40,7 +40,7 @@ from marvin.lib.base import (EgressFireWallRule,
from marvin.lib.common import (get_domain,
get_template,
get_zone)
from marvin.cloudstackAPI import restartVPC
from marvin.cloudstackAPI import restartVPC, listNuageUnderlayVlanIpRanges
# Import System Modules
import importlib
import functools
@ -139,7 +139,7 @@ class nuageTestCase(cloudstackTestCase):
cls.api_client,
physicalnetworkid=cls.vsp_physical_network.id)[0]
# Take username and password from the datacenter config file,
# Get username and password from the Marvin config file,
# as they are not returned by the API.
config_nuage_device = next(device for zone in cls.config.zones
if zone.name == cls.zone.name
@ -156,6 +156,36 @@ class nuageTestCase(cloudstackTestCase):
cls.tearDownClass()
raise unittest.SkipTest("Warning: Could not get configured "
"Nuage VSP device details - %s" % e)
# Get data center Internet connectivity information from the Marvin
# config file, which is required to perform Internet connectivity and
# traffic tests from the guest VMs.
cls.isInternetConnectivityAvailable = False
cls.http_proxy = None
cls.https_proxy = None
dc_internet_conn_info = cls.config.dcInternetConnectivityInfo if \
cls.config.dcInternetConnectivityInfo else None
if dc_internet_conn_info:
dc_internet_conn_available = dc_internet_conn_info.available if \
dc_internet_conn_info.available else None
if dc_internet_conn_available:
cls.isInternetConnectivityAvailable = True if \
dc_internet_conn_available == "true" else False
dc_internet_conn_http_proxy = dc_internet_conn_info.httpProxy if \
dc_internet_conn_info.httpProxy else None
if dc_internet_conn_http_proxy:
cls.http_proxy = dc_internet_conn_http_proxy
dc_internet_conn_https_proxy = dc_internet_conn_info.httpsProxy \
if dc_internet_conn_info.httpsProxy else None
if dc_internet_conn_https_proxy:
cls.https_proxy = dc_internet_conn_https_proxy
# Check if the configured Nuage VSP SDN platform infrastructure
# supports underlay networking
cmd = listNuageUnderlayVlanIpRanges.listNuageUnderlayVlanIpRangesCmd()
cmd.underlay = True
cls.isNuageInfraUnderlay = isinstance(
cls.api_client.listNuageUnderlayVlanIpRanges(cmd), list)
return
@classmethod
@ -596,8 +626,11 @@ class nuageTestCase(cloudstackTestCase):
# wget_from_server - Fetches file with the given file name from a web
# server listening on the given public IP address and port
def wget_from_server(self, public_ip, port, file_name="index.html"):
def wget_from_server(self, public_ip, port=80, file_name="index.html",
disable_system_proxies=True):
import urllib
if disable_system_proxies:
urllib.getproxies = lambda: {}
self.debug("wget file - %s from a http web server listening on "
"public IP address - %s and port - %s" %
(file_name, public_ip.ipaddress.ipaddress, port))
@ -606,6 +639,9 @@ class nuageTestCase(cloudstackTestCase):
(public_ip.ipaddress.ipaddress, port, file_name),
filename=file_name
)
self.debug("Successful to wget file - %s from a http web server "
"listening on public IP address - %s and port - %s" %
(file_name, public_ip.ipaddress.ipaddress, port))
return filename, headers
# validate_NetworkServiceProvider - Validates the given Network Service
@ -971,6 +1007,20 @@ class nuageTestCase(cloudstackTestCase):
self.assertEqual(vsd_fip.assigned, True,
"Floating IP in VSD should be assigned"
)
ext_fip_subnet_filter = self.get_externalID_filter(
public_ipaddress.vlanid)
vsd_fip_subnet = self.vsd.get_shared_network_resource(
filter=ext_fip_subnet_filter)
if self.isNuageInfraUnderlay:
self.assertEqual(vsd_fip_subnet.underlay, True,
"Floating IP subnet in VSD should be underlay "
"enabled"
)
else:
self.assertEqual(vsd_fip_subnet.underlay, False,
"Floating IP subnet in VSD should be underlay "
"disabled"
)
ext_network_filter = self.get_externalID_filter(vpc.id) if vpc \
else self.get_externalID_filter(network.id)
vsd_domain = self.vsd.get_domain(filter=ext_network_filter)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -763,6 +763,14 @@ test_data = {
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"dns_rule": {
"privateport": 53,
"publicport": 53,
"startport": 53,
"endport": 53,
"protocol": "UDP",
"cidrlist": '0.0.0.0/0',
},
"icmprule": {
"icmptype": -1,
"icmpcode": -1,