Merge pull request #1580 from nlivens/nuage_vsp_pat_fip2ul

CLOUDSTACK-9402 : Support for underlay features (Source & Static NAT to underlay) in Nuage VSP pluginSupport for underlay features (Source & Static NAT to underlay) with Nuage VSP SDN Plugin including Marvin test coverage for corresponding Source & Static NAT features on master. Moreover, our Marvin tests are written in such a way that they can validate our supported feature set with both Nuage VSP SDN platform's overlay and underlay infra.

PR contents:
1) Support for Source NAT to underlay feature on master with Nuage VSP SDN Plugin.
2) Support for Static NAT to underlay feature on master with Nuage VSP SDN Plugin.
3) Marvin test coverage for Source & Static NAT to underlay on master with Nuage VSP SDN Plugin.
4) Enhancements on our exiting Marvin test code (nuagevsp plugins directory).
5) PEP8 & PyFlakes compliance with our Marvin test code.

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

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2016-11-25 13:28:29 +05:30
commit 62c8496d7e
No known key found for this signature in database
GPG Key ID: 484248210EE3D884
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,