mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-10053: Performance improvement: caching of NuageVsp ID
* VSP ID Caching * VSP call Statistics * 5.0 Support Co-Authored-By: Frank Maximus <frank.maximus@nuagenetworks.net> Co-Authored-By: Raf Smeets <raf.smeets@nuagenetworks.net>
This commit is contained in:
parent
285fd77674
commit
0871ff9eda
@ -48,6 +48,8 @@ public interface NicSecondaryIpDao extends GenericDao<NicSecondaryIpVO, Long> {
|
||||
|
||||
NicSecondaryIpVO findByIp4AddressAndNicId(String ip4Address, long nicId);
|
||||
|
||||
NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp);
|
||||
|
||||
NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp);
|
||||
|
||||
List<String> getSecondaryIpAddressesForNic(long nicId);
|
||||
|
||||
@ -119,8 +119,10 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long
|
||||
|
||||
@Override
|
||||
public NicSecondaryIpVO findByIp4AddressAndNetworkId(String ip4Address, long networkId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("network", networkId);
|
||||
sc.setParameters("address", ip4Address);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -131,6 +133,14 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase<NicSecondaryIpVO, Long
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicSecondaryIpVO findByIp4AddressAndInstanceId(Long vmId, String vmIp) {
|
||||
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("instanceId", vmId);
|
||||
sc.setParameters("address", vmIp);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp) {
|
||||
SearchCriteria<NicSecondaryIpVO> sc = AllFieldsSearch.create();
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<nuage.vsp.client.version>1.0.1</nuage.vsp.client.version>
|
||||
<nuage.vsp.client.version>1.0.5</nuage.vsp.client.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
//
|
||||
// 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 net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
|
||||
|
||||
/**
|
||||
* Created by sgoeminn on 3/24/17.
|
||||
*/
|
||||
public class ImplementNetworkVspAnswer extends Answer {
|
||||
private NetworkRelatedVsdIds networkRelatedVsdIds;
|
||||
|
||||
public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, NetworkRelatedVsdIds networkRelatedVsdIds) {
|
||||
super(command);
|
||||
this.networkRelatedVsdIds = networkRelatedVsdIds;
|
||||
}
|
||||
|
||||
public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, Exception e) {
|
||||
super(command, e);
|
||||
}
|
||||
|
||||
public NetworkRelatedVsdIds getNetworkRelatedVsdIds() {
|
||||
return networkRelatedVsdIds;
|
||||
}
|
||||
}
|
||||
@ -29,8 +29,6 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
@ -40,8 +38,11 @@ import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
@ -521,9 +522,18 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId());
|
||||
checkVlanUnderlayCompatibility(sourceNatVlan);
|
||||
|
||||
if (!staticNat.isForRevoke()) {
|
||||
final List<FirewallRuleVO> firewallRules = _firewallRulesDao.listByIpAndNotRevoked(staticNat.getSourceIpAddressId());
|
||||
for (FirewallRuleVO firewallRule : firewallRules) {
|
||||
_nuageVspEntityBuilder.buildVspAclRule(firewallRule, config, sourceNatIp);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@ -632,7 +642,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
@Override
|
||||
public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
|
||||
List<VpcOfferingServiceMapVO> vpcOfferingServices = _vpcOfferingSrvcDao.listByVpcOffId(vpc.getVpcOfferingId());
|
||||
Map<Network.Service, Set<Network.Provider>> supportedVpcServices = NuageVspManagerImpl.NUAGE_VSP_VPC_SERVICE_MAP;
|
||||
Multimap<Service, Provider> supportedVpcServices = NuageVspManagerImpl.NUAGE_VSP_VPC_SERVICE_MAP;
|
||||
for (VpcOfferingServiceMapVO vpcOfferingService : vpcOfferingServices) {
|
||||
Network.Service service = Network.Service.getService(vpcOfferingService.getService());
|
||||
if (!supportedVpcServices.containsKey(service)) {
|
||||
@ -641,7 +651,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
|
||||
}
|
||||
|
||||
Network.Provider provider = Network.Provider.getProvider(vpcOfferingService.getProvider());
|
||||
if (!supportedVpcServices.get(service).contains(provider)) {
|
||||
if (!supportedVpcServices.containsEntry(service, provider)) {
|
||||
s_logger.warn(String.format("NuageVsp doesn't support provider %s for service %s for VPCs", provider.getName(), service.getName()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -25,9 +25,25 @@ import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.apache.cloudstack.resourcedetail.VpcDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
@ -36,6 +52,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.ImplementNetworkVspAnswer;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
@ -82,20 +99,6 @@ import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
|
||||
public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class);
|
||||
@ -154,6 +157,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
return networkObject;
|
||||
}
|
||||
|
||||
/** In case an externalId is specified, we get called here, and store the id the same way as cached data */
|
||||
@Override
|
||||
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException {
|
||||
long networkId = network.getId();
|
||||
@ -206,7 +210,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
|
||||
implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
|
||||
|
||||
if (!implement(physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
|
||||
if (!implement(network.getVpcId(), physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -227,10 +231,10 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
return implemented;
|
||||
}
|
||||
|
||||
private boolean implement(long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) {
|
||||
private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) {
|
||||
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
|
||||
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption);
|
||||
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
ImplementNetworkVspAnswer answer = (ImplementNetworkVspAnswer) _agentMgr.easySend(nuageVspHost.getId(), cmd);
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
|
||||
if ((null != answer) && (null != answer.getDetails())) {
|
||||
@ -238,9 +242,54 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
saveNetworkAndVpcDetails(vspNetwork, answer.getNetworkRelatedVsdIds(), vpcId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void saveNetworkAndVpcDetails(VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds, Long vpcId) {
|
||||
|
||||
|
||||
if (!vspNetwork.isShared() && !vspNetwork.getNetworkRelatedVsdIds().equals(networkRelatedVsdIds)) {
|
||||
Map<String, String> networkDetails = constructNetworkDetails(networkRelatedVsdIds, vspNetwork.isVpc());
|
||||
|
||||
for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
|
||||
NetworkDetailVO networkDetailVO = new NetworkDetailVO(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue(), false);
|
||||
_networkDetailsDao.persist(networkDetailVO);
|
||||
}
|
||||
|
||||
if(vspNetwork.isVpc()) {
|
||||
Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);
|
||||
|
||||
for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
|
||||
VpcDetailVO vpcDetailVO = new VpcDetailVO(vpcId, vpcDetail.getKey(), vpcDetail.getValue(), false);
|
||||
_vpcDetailsDao.persist(vpcDetailVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String> constructNetworkDetails(NetworkRelatedVsdIds networkRelatedVsdIds, boolean isVpc) {
|
||||
Map<String, String> networkDetails = Maps.newHashMap();
|
||||
|
||||
if(!isVpc) {
|
||||
networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
|
||||
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
|
||||
}
|
||||
networkRelatedVsdIds.getVsdSubnetId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, v));
|
||||
|
||||
return networkDetails;
|
||||
}
|
||||
|
||||
private static Map<String, String> constructVpcDetails(NetworkRelatedVsdIds networkRelatedVsdIds) {
|
||||
Map<String, String> vpcDetails = Maps.newHashMap();
|
||||
|
||||
networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
|
||||
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
|
||||
|
||||
return vpcDetails;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
|
||||
if (vm.getType() != VirtualMachine.Type.DomainRouter && _nuageVspEntityBuilder.usesVirtualRouter(network.getNetworkOfferingId())) {
|
||||
@ -303,7 +352,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
|
||||
// Make sure the shared network is present
|
||||
NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
if (!implement(network.getPhysicalNetworkId(), vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
|
||||
if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
|
||||
s_logger.error("Failed to implement shared network " + network.getUuid() + " under domain " + context.getDomain().getUuid());
|
||||
throw new InsufficientVirtualNetworkCapacityException("Failed to implement shared network " + network.getUuid() + " under domain " +
|
||||
context.getDomain().getUuid(), Network.class, network.getId());
|
||||
@ -404,25 +453,22 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
private void checkMultipleSubnetsCombinedWithUseData(Network network) {
|
||||
if (_ntwkOfferingSrvcDao.listServicesForNetworkOffering(network.getNetworkOfferingId()).contains(Network.Service.UserData.getName())) {
|
||||
List<VlanVO> vlanVOs = _vlanDao.listVlansByNetworkId(network.getId());
|
||||
if (vlanVOs.size() > 1) {
|
||||
VlanVO vlanVoItem = vlanVOs.get(0);
|
||||
for (VlanVO VlanVoItem2 : FluentIterable.from(vlanVOs).skip(1)) {
|
||||
if (!vlanVoItem.equals(VlanVoItem2)
|
||||
&& !VlanVoItem2.getVlanGateway().equals(vlanVoItem.getVlanGateway())) {
|
||||
if (vlanVOs.stream()
|
||||
.map(VlanVO::getVlanGateway)
|
||||
.distinct()
|
||||
.count() > 1) {
|
||||
s_logger.error("NuageVsp provider does not support multiple subnets in combination with user data. Network: " + network + ", vlans: " + vlanVOs);
|
||||
throw new UnsupportedServiceException("NuageVsp provider does not support multiple subnets in combination with user data.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) {
|
||||
if (networkType == NetworkType.Advanced
|
||||
&& isMyTrafficType(offering.getTrafficType())
|
||||
&& isMyIsolationMethod(physicalNetwork)
|
||||
&& (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.Shared)
|
||||
&& (offering.getGuestType() == GuestType.Isolated || offering.getGuestType() == GuestType.Shared)
|
||||
&& hasRequiredServices(offering)) {
|
||||
if (_configMgr.isOfferingForVpc(offering) && !offering.getIsPersistent()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
@ -578,11 +624,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
|
||||
? Long.valueOf(nic.getNetworkId())
|
||||
: getDefaultNetwork(nic.getInstanceId());
|
||||
|
||||
Boolean hasDns = cache.get(networkId);
|
||||
if (hasDns == null) {
|
||||
hasDns = networkHasDns(_networkDao.findById(networkId));
|
||||
cache.put(networkId, hasDns);
|
||||
}
|
||||
Boolean hasDns = cache.computeIfAbsent(networkId, k -> networkHasDns(_networkDao.findById(networkId)));
|
||||
return hasDns;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,91 @@
|
||||
//
|
||||
// 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.network.manager;
|
||||
|
||||
import com.cloud.agent.Listener;
|
||||
import com.cloud.agent.api.AgentControlAnswer;
|
||||
import com.cloud.agent.api.AgentControlCommand;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Status;
|
||||
|
||||
/**
|
||||
* Created by maximusf on 7/19/17.
|
||||
*/
|
||||
abstract class AbstractListener implements Listener {
|
||||
|
||||
@Override
|
||||
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processCommands(long agentId, long seq, Command[] commands) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostAdded(long hostId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDisconnect(long agentId, Status state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostAboutToBeRemoved(long hostId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostRemoved(long hostId, long clusterId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecurring() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processTimeout(long agentId, long seq) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -36,21 +36,21 @@ import java.util.List;
|
||||
|
||||
public interface NuageVspManager extends PluggableService {
|
||||
|
||||
static final String nuageVspSharedNetworkOfferingWithSGServiceName = "DefaultNuageVspSharedNetworkOfferingWithSGService";
|
||||
String nuageVspSharedNetworkOfferingWithSGServiceName = "DefaultNuageVspSharedNetworkOfferingWithSGService";
|
||||
|
||||
static final String nuageVPCOfferingName = "Nuage VSP VPC Offering";
|
||||
String nuageVPCOfferingName = "Nuage VSP VPC Offering";
|
||||
|
||||
static final String nuageVPCOfferingDisplayText = "Nuage VSP VPC Offering";
|
||||
String nuageVPCOfferingDisplayText = "Nuage VSP VPC Offering";
|
||||
|
||||
static final String nuageDomainTemplateDetailName = "domainTemplateName";
|
||||
String nuageDomainTemplateDetailName = "domainTemplateName";
|
||||
|
||||
static final String nuageUnderlayVlanIpRangeDetailKey = "nuage.underlay";
|
||||
String nuageUnderlayVlanIpRangeDetailKey = "nuage.underlay";
|
||||
|
||||
static final ConfigKey<Boolean> NuageVspConfigDns = new ConfigKey<Boolean>(Boolean.class, "nuagevsp.configure.dns", "Advanced", "true",
|
||||
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);
|
||||
|
||||
static final ConfigKey<Boolean> NuageVspDnsExternal = new ConfigKey<Boolean>(
|
||||
ConfigKey<Boolean> NuageVspDnsExternal = new ConfigKey<Boolean>(
|
||||
Boolean.class,
|
||||
"nuagevsp.dns.external",
|
||||
"Advanced",
|
||||
@ -61,18 +61,24 @@ public interface NuageVspManager extends PluggableService {
|
||||
+ "If nuagevsp.configure.dns is false, DNS server will not be configured in the VM. Default value for this flag is true",
|
||||
true, Scope.Global, null);
|
||||
|
||||
static final ConfigKey<String> NuageVspConfigGateway = new ConfigKey<String>(String.class, "nuagevsp.configure.gateway.systemid", "Advanced", "",
|
||||
ConfigKey<String> NuageVspConfigGateway = new ConfigKey<String>(String.class, "nuagevsp.configure.gateway.systemid", "Advanced", "",
|
||||
"Defines the systemID of the gateway configured in VSP", true, Scope.Global, null);
|
||||
|
||||
static final ConfigKey<String> NuageVspSharedNetworkDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.sharedntwk.domaintemplate.name",
|
||||
ConfigKey<String> NuageVspSharedNetworkDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.sharedntwk.domaintemplate.name",
|
||||
"Advanced", "", "Defines if NuageVsp plugin needs to use pre created Domain Template configured in VSP for shared networks", true, Scope.Global, null);
|
||||
|
||||
static final ConfigKey<String> NuageVspVpcDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.vpc.domaintemplate.name",
|
||||
ConfigKey<String> NuageVspVpcDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.vpc.domaintemplate.name",
|
||||
"Advanced", "", "Defines if NuageVsp plugin needs to use pre created Domain Template configured in VSP for VPCs", true, Scope.Global, null);
|
||||
|
||||
static final ConfigKey<String> NuageVspIsolatedNetworkDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.isolatedntwk.domaintemplate.name",
|
||||
ConfigKey<String> NuageVspIsolatedNetworkDomainTemplateName = new ConfigKey<String>(String.class, "nuagevsp.isolatedntwk.domaintemplate.name",
|
||||
"Advanced", "", "Defines if NuageVsp plugin needs to use pre created Domain Template configured in VSP for isolated networks", true, Scope.Global, null);
|
||||
|
||||
String NETWORK_METADATA_VSD_DOMAIN_ID = "vsdDomainId";
|
||||
|
||||
String NETWORK_METADATA_VSD_ZONE_ID = "vsdZoneId";
|
||||
|
||||
String NETWORK_METADATA_VSD_SUBNET_ID = "vsdSubnetId";
|
||||
|
||||
NuageVspDeviceVO addNuageVspDevice(AddNuageVspDeviceCmd cmd);
|
||||
|
||||
NuageVspDeviceVO updateNuageVspDevice(UpdateNuageVspDeviceCmd cmd);
|
||||
|
||||
@ -19,17 +19,16 @@
|
||||
|
||||
package com.cloud.network.manager;
|
||||
|
||||
import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
@ -41,17 +40,19 @@ import net.nuage.vsp.acs.client.api.model.VspHost;
|
||||
import net.nuage.vsp.acs.client.common.NuageVspApiVersion;
|
||||
import net.nuage.vsp.acs.client.common.NuageVspConstants;
|
||||
|
||||
import net.nuage.vsp.acs.client.exception.NuageVspException;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
@ -59,17 +60,13 @@ import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
|
||||
import org.apache.cloudstack.network.ExternalNetworkDeviceManager;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.Listener;
|
||||
import com.cloud.agent.api.AgentControlAnswer;
|
||||
import com.cloud.agent.api.AgentControlCommand;
|
||||
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.CleanUpDomainCommand;
|
||||
import com.cloud.agent.api.manager.EntityExistsCommand;
|
||||
import com.cloud.agent.api.manager.GetApiDefaultsAnswer;
|
||||
@ -99,7 +96,6 @@ import com.cloud.dc.dao.VlanDetailsDao;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.host.DetailVO;
|
||||
import com.cloud.host.Host;
|
||||
@ -153,11 +149,13 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
|
||||
import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType;
|
||||
|
||||
public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, Configurable, StateListener<Status, Status.Event, Host> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(NuageVspManagerImpl.class);
|
||||
|
||||
public static final Map<Network.Service, Set<Network.Provider>> NUAGE_VSP_VPC_SERVICE_MAP;
|
||||
public static final Multimap<Network.Service, Network.Provider> NUAGE_VSP_VPC_SERVICE_MAP;
|
||||
private static final ConfigKey[] NUAGE_VSP_CONFIG_KEYS = new ConfigKey<?>[] { NuageVspConfigDns, NuageVspDnsExternal, NuageVspConfigGateway,
|
||||
NuageVspSharedNetworkDomainTemplateName, NuageVspVpcDomainTemplateName, NuageVspIsolatedNetworkDomainTemplateName };
|
||||
public static final String CMSID_CONFIG_KEY = "nuagevsp.cms.id";
|
||||
@ -222,23 +220,32 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
Set<Network.Provider> nuageVspProviders = ImmutableSet.of(Network.Provider.NuageVsp);
|
||||
Set<Network.Provider> vrProviders = ImmutableSet.of(Network.Provider.VPCVirtualRouter);
|
||||
Set<Network.Provider> lbProviders = ImmutableSet.of(Network.Provider.InternalLbVm);
|
||||
NUAGE_VSP_VPC_SERVICE_MAP = ImmutableMap.<Network.Service, Set<Network.Provider>>builder()
|
||||
.put(Network.Service.Connectivity, nuageVspProviders)
|
||||
.put(Network.Service.Gateway, nuageVspProviders)
|
||||
.put(Network.Service.Dhcp, nuageVspProviders)
|
||||
.put(Network.Service.StaticNat, nuageVspProviders)
|
||||
.put(Network.Service.SourceNat, nuageVspProviders)
|
||||
.put(Network.Service.NetworkACL, nuageVspProviders)
|
||||
.put(Network.Service.UserData, vrProviders)
|
||||
.put(Network.Service.Lb, lbProviders)
|
||||
.put(Network.Service.Dns, vrProviders)
|
||||
NUAGE_VSP_VPC_SERVICE_MAP = ImmutableMultimap.<Network.Service, Network.Provider>builder()
|
||||
.putAll(Network.Service.Connectivity, nuageVspProviders)
|
||||
.putAll(Network.Service.Gateway, nuageVspProviders)
|
||||
.putAll(Network.Service.Dhcp, nuageVspProviders)
|
||||
.putAll(Network.Service.StaticNat, nuageVspProviders)
|
||||
.putAll(Network.Service.SourceNat, nuageVspProviders)
|
||||
.putAll(Network.Service.NetworkACL, nuageVspProviders)
|
||||
.putAll(Network.Service.UserData, vrProviders)
|
||||
.putAll(Network.Service.Lb, lbProviders)
|
||||
.putAll(Network.Service.Dns, vrProviders)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Listener _nuageVspResourceListener;
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
return Lists.<Class<?>>newArrayList(AddNuageVspDeviceCmd.class, DeleteNuageVspDeviceCmd.class, ListNuageVspDevicesCmd.class,
|
||||
UpdateNuageVspDeviceCmd.class, EnableNuageUnderlayVlanIpRangeCmd.class, DisableNuageUnderlayVlanIpRangeCmd.class, ListNuageUnderlayVlanIpRangesCmd.class);
|
||||
return Lists.<Class<?>>newArrayList(
|
||||
AddNuageVspDeviceCmd.class,
|
||||
DeleteNuageVspDeviceCmd.class,
|
||||
ListNuageVspDevicesCmd.class,
|
||||
UpdateNuageVspDeviceCmd.class,
|
||||
EnableNuageUnderlayVlanIpRangeCmd.class,
|
||||
DisableNuageUnderlayVlanIpRangeCmd.class,
|
||||
ListNuageUnderlayVlanIpRangesCmd.class
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -298,19 +305,15 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
}
|
||||
apiVersion = cmd.getApiVersion();
|
||||
} else {
|
||||
boolean apiVersionFound = false;
|
||||
Map<NuageVspApiVersion, NuageVspApiVersion.Status> supportedVersions = clientLoader.getNuageVspManagerClient().getSupportedVersions();
|
||||
for (NuageVspApiVersion selectedVersion : supportedVersions.keySet()) {
|
||||
if (supportedVersions.get(selectedVersion) == NuageVspApiVersion.Status.CURRENT){
|
||||
apiVersion = selectedVersion.toString();
|
||||
apiVersionFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<NuageVspApiVersion> supportedVsdVersions = clientLoader.getNuageVspManagerClient().getSupportedVersionList();
|
||||
supportedVsdVersions.retainAll(Arrays.asList(NuageVspApiVersion.SUPPORTED_VERSIONS));
|
||||
|
||||
if(!apiVersionFound) {
|
||||
if(supportedVsdVersions.isEmpty()) {
|
||||
throw new CloudRuntimeException("No supported API version found!");
|
||||
}
|
||||
|
||||
supportedVsdVersions.sort(Comparator.reverseOrder());
|
||||
apiVersion = supportedVsdVersions.get(0).toString();
|
||||
}
|
||||
|
||||
|
||||
@ -365,7 +368,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
} catch (ConfigurationException e) {
|
||||
s_logger.error("Failed to configure Nuage VSD resource " + cmd.getHostName(), e);
|
||||
throw new CloudRuntimeException("Failed to configure Nuage VSD resource " + cmd.getHostName(), e);
|
||||
} catch (ExecutionException ee) {
|
||||
} catch (NuageVspException ee) {
|
||||
s_logger.error("Failed to add Nuage VSP device " + cmd.getHostName(), ee);
|
||||
throw new CloudRuntimeException("Failed to add Nuage VSP device " + cmd.getHostName(), ee);
|
||||
}
|
||||
@ -677,7 +680,12 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
return answer != null && answer.getSuccess();
|
||||
}
|
||||
|
||||
private void auditHost(HostVO host) {
|
||||
void auditHost(long hostId) {
|
||||
Host host = _hostDao.findById(hostId);
|
||||
auditHost((HostVO)host);
|
||||
}
|
||||
|
||||
void auditHost(HostVO host) {
|
||||
if (host == null) return;
|
||||
|
||||
_hostDao.loadDetails(host);
|
||||
@ -897,9 +905,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
@DB
|
||||
private void initMessageBusListeners() {
|
||||
// Create corresponding enterprise and profile in VSP when creating a CS Domain
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_ADD_DOMAIN_EVENT, new MessageSubscriber() {
|
||||
@Override
|
||||
public void onPublishMessage(String senderAddress, String subject, Object args) {
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_ADD_DOMAIN_EVENT, (senderAddress, subject, args) -> {
|
||||
Long domainId = (Long) args;
|
||||
Domain domain = _domainDao.findById(domainId);
|
||||
|
||||
@ -915,13 +921,10 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
} finally {
|
||||
_domainDao.releaseFromLockTable(domain.getId());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Clean up corresponding resources in VSP when deleting a CS Domain
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_PRE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() {
|
||||
@Override
|
||||
public void onPublishMessage(String senderAddress, String subject, Object args) {
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_PRE_REMOVE_DOMAIN_EVENT, (senderAddress, subject, args) -> {
|
||||
DomainVO domain = (DomainVO) args;
|
||||
List<NuageVspDeviceVO> nuageVspDevices = _nuageVspDao.listAll();
|
||||
for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) {
|
||||
@ -929,13 +932,10 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
CleanUpDomainCommand cmd = new CleanUpDomainCommand(vspDomainCleanUp);
|
||||
_agentMgr.easySend(nuageVspDevice.getHostId(), cmd);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Delete corresponding enterprise and profile in VSP when deleting a CS Domain
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() {
|
||||
@Override
|
||||
public void onPublishMessage(String senderAddress, String subject, Object args) {
|
||||
_messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, (senderAddress, subject, args) -> {
|
||||
DomainVO domain = (DomainVO) args;
|
||||
List<NuageVspDeviceVO> nuageVspDevices = _nuageVspDao.listAll();
|
||||
for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) {
|
||||
@ -943,78 +943,28 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
SyncDomainCommand syncCmd = new SyncDomainCommand(vspDomain, SyncDomainCommand.Type.REMOVE);
|
||||
_agentMgr.easySend(nuageVspDevice.getHostId(), syncCmd);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@DB
|
||||
private void initNuageVspResourceListeners() {
|
||||
_agentMgr.registerForHostEvents(new Listener() {
|
||||
@Override
|
||||
public boolean processAnswers(long agentId, long seq, Answer[] answers) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private class NuageVspResourceListener extends AbstractListener {
|
||||
@Override
|
||||
public boolean processCommands(long agentId, long seq, Command[] commands) {
|
||||
if (commands != null && commands.length == 1) {
|
||||
Command command = commands[0];
|
||||
if (command instanceof PingNuageVspCommand) {
|
||||
PingNuageVspCommand pingNuageVspCommand = (PingNuageVspCommand) command;
|
||||
PingNuageVspCommand pingNuageVspCommand = (PingNuageVspCommand)command;
|
||||
if (pingNuageVspCommand.shouldAudit()) {
|
||||
Host host = _hostDao.findById(pingNuageVspCommand.getHostId());
|
||||
auditHost((HostVO) host);
|
||||
auditHost(pingNuageVspCommand.getHostId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostAdded(long hostId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDisconnect(long agentId, Status state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostAboutToBeRemoved(long hostId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHostRemoved(long hostId, long clusterId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecurring() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeout() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processTimeout(long agentId, long seq) {
|
||||
return true;
|
||||
}
|
||||
}, false, true, false);
|
||||
@DB
|
||||
private void initNuageVspResourceListeners() {
|
||||
_agentMgr.registerForHostEvents(new NuageVspResourceListener(), false, true, false);
|
||||
}
|
||||
|
||||
@DB
|
||||
@ -1070,11 +1020,13 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
}
|
||||
|
||||
@DB
|
||||
protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap, final boolean isDefault,
|
||||
protected VpcOffering createVpcOffering(final String name, final String displayText, final Multimap<Network.Service, Network.Provider> svcProviderMap, final boolean isDefault,
|
||||
final VpcOffering.State state, final Long serviceOfferingId) {
|
||||
return Transaction.execute(new TransactionCallback<VpcOffering>() {
|
||||
@Override
|
||||
public VpcOffering doInTransaction(TransactionStatus status) {
|
||||
return Transaction.execute((TransactionCallback<VpcOffering>)status -> createVpcOfferingInTransaction(name, displayText, svcProviderMap, isDefault, state, serviceOfferingId));
|
||||
}
|
||||
|
||||
private VpcOffering createVpcOfferingInTransaction(String name, String displayText, Multimap<Network.Service, Network.Provider> svcProviderMap, boolean isDefault,
|
||||
VpcOffering.State state, Long serviceOfferingId) {
|
||||
// create vpc offering object
|
||||
VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, false, false);
|
||||
|
||||
@ -1087,63 +1039,56 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager,
|
||||
offering = _vpcOffDao.persist(offering);
|
||||
// populate services and providers
|
||||
if (svcProviderMap != null) {
|
||||
for (Network.Service service : svcProviderMap.keySet()) {
|
||||
Set<Network.Provider> providers = svcProviderMap.get(service);
|
||||
if (providers != null && !providers.isEmpty()) {
|
||||
for (Network.Provider provider : providers) {
|
||||
for (Map.Entry<Network.Service, Network.Provider> entry : svcProviderMap.entries()) {
|
||||
Network.Service service = entry.getKey();
|
||||
Network.Provider provider = entry.getValue();
|
||||
|
||||
VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
|
||||
_vpcOffSvcMapDao.persist(offService);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("Added service for the vpc offering: %s with provider %s", offService, provider.getName()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException(String.format("Provider is missing for the VPC offering service %s", service.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offering;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void updateVpcOffering(final VpcOffering offering, final Map<Network.Service, Set<Network.Provider>> svcProviderMap) {
|
||||
Transaction.execute(new TransactionCallback<VpcOffering>() {
|
||||
@Override
|
||||
public VpcOffering doInTransaction(TransactionStatus status) {
|
||||
protected void updateVpcOffering(final VpcOffering offering, final Multimap<Network.Service, Network.Provider> svcProviderMap) {
|
||||
Transaction.execute((TransactionCallback<VpcOffering>)status -> updateVpcOfferingInTransaction(offering, svcProviderMap));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private VpcOffering updateVpcOfferingInTransaction(VpcOffering offering, Multimap<Network.Service, Network.Provider> svcProviderMap) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("Updating vpc offering %s", offering));
|
||||
}
|
||||
|
||||
List<VpcOfferingServiceMapVO> currentVpcOfferingServices = _vpcOffSvcMapDao.listByVpcOffId(offering.getId());
|
||||
Map<Network.Service, Set<Network.Provider>> currentSvcProviderMap = Maps.newHashMap();
|
||||
Multimap<Network.Service, Network.Provider> currentSvcProviderMap = HashMultimap.create();
|
||||
for (VpcOfferingServiceMapVO vpcOfferingService : currentVpcOfferingServices) {
|
||||
Network.Service service = Network.Service.getService(vpcOfferingService.getService());
|
||||
Network.Provider provider = Network.Provider.getProvider(vpcOfferingService.getProvider());
|
||||
|
||||
if (!currentSvcProviderMap.containsKey(service)) {
|
||||
currentSvcProviderMap.put(service, Sets.newHashSet(provider));
|
||||
} else if (!currentSvcProviderMap.get(service).contains(provider)) {
|
||||
currentSvcProviderMap.get(service).add(provider);
|
||||
}
|
||||
currentSvcProviderMap.put(service, provider);
|
||||
}
|
||||
|
||||
for (Network.Service service : svcProviderMap.keySet()) {
|
||||
for (Network.Provider provider : svcProviderMap.get(service)) {
|
||||
if (currentSvcProviderMap.get(service) == null || !currentSvcProviderMap.get(service).contains(provider)) {
|
||||
for (Map.Entry<Network.Service, Network.Provider> entry : svcProviderMap.entries()) {
|
||||
Network.Service service = entry.getKey();
|
||||
Network.Provider provider = entry.getValue();
|
||||
|
||||
if (!currentSvcProviderMap.containsEntry(service, provider)) {
|
||||
VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
|
||||
_vpcOffSvcMapDao.persist(offService);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("Added service for the vpc offering: %s", offService));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return offering;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private HostVO findNuageVspHost(long hostId) {
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
|
||||
@ -20,7 +20,8 @@
|
||||
package com.cloud.network.resource;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
@ -31,6 +32,8 @@ import net.nuage.vsp.acs.client.api.NuageVspGuruClient;
|
||||
import net.nuage.vsp.acs.client.api.NuageVspManagerClient;
|
||||
import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader;
|
||||
import net.nuage.vsp.acs.client.api.model.VspHost;
|
||||
import net.nuage.vsp.acs.client.common.RequestType;
|
||||
import net.nuage.vsp.acs.client.common.model.NuageVspEntity;
|
||||
import net.nuage.vsp.acs.client.exception.NuageVspException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
@ -48,8 +51,9 @@ import com.cloud.host.Host;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.mgmt.JmxUtil;
|
||||
|
||||
public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
public class NuageVspResource extends ManagerBase implements ServerResource, VspStatisticsMBean {
|
||||
private static final Logger s_logger = Logger.getLogger(NuageVspResource.class);
|
||||
|
||||
private String _guid;
|
||||
@ -73,7 +77,7 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
|
||||
|
||||
if (!newVspHost.getApiVersion().isSupported()) {
|
||||
s_logger.warn(String.format("[UPGRADE] API version %s of Nuage Vsp Device %s should be updated.", _vspHost.getApiVersion(), configuration.hostName()));
|
||||
s_logger.warn(String.format("[UPGRADE] API version %s of Nuage Vsp Device %s should be updated.", newVspHost.getApiVersion(), configuration.hostName()));
|
||||
}
|
||||
|
||||
_guid = configuration.guid();
|
||||
@ -87,7 +91,7 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
|
||||
_vspHost = newVspHost;
|
||||
_clientLoader = clientLoader;
|
||||
} catch (ExecutionException e) {
|
||||
} catch (NuageVspException e) {
|
||||
s_logger.error(e.getMessage(), e);
|
||||
throw new CloudRuntimeException(e.getMessage(), e);
|
||||
}
|
||||
@ -95,6 +99,64 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
return _vspHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVSDStatistics() {
|
||||
return _clientLoader.getNuageVspStatistics().getVsdCount();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByEntityType(String entity) {
|
||||
try {
|
||||
NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
|
||||
return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByRequestType(String requestType) {
|
||||
try {
|
||||
RequestType requestTypeValue = RequestType.valueOf(requestType);
|
||||
return _clientLoader.getNuageVspStatistics().getVsdCount(requestTypeValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByEntityAndRequestType(String entity, String requestType) {
|
||||
try {
|
||||
RequestType requestTypeValue = RequestType.valueOf(requestType);
|
||||
NuageVspEntity nuageVspEntity = NuageVspEntity.valueOf(entity);
|
||||
return _clientLoader.getNuageVspStatistics().getVsdCount(nuageVspEntity, requestTypeValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, AtomicLong> convertHashMap(Map<RequestType, AtomicLong> map) {
|
||||
return map.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> e.getKey().toString(),
|
||||
Map.Entry::getValue)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, AtomicLong>> getVsdStatisticsReport() {
|
||||
return _clientLoader.getNuageVspStatistics()
|
||||
.getVsdCountReport()
|
||||
.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> e.getKey().toString(),
|
||||
e -> convertHashMap(e.getValue())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
if(super.configure(name, params)) {
|
||||
@ -113,11 +175,25 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
try {
|
||||
JmxUtil.registerMBean("NuageVspResource", _name, new VspStatisticsMBeanImpl(this));
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Unable to initialize statistics Mbean", e);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
|
||||
try {
|
||||
JmxUtil.unregisterMBean("NuageVspResource", _name);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Unable to initialize inaccurate clock", e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -155,7 +231,7 @@ public class NuageVspResource extends ManagerBase implements ServerResource {
|
||||
|
||||
try {
|
||||
login();
|
||||
} catch (ExecutionException | ConfigurationException e) {
|
||||
} catch (NuageVspException | ConfigurationException e) {
|
||||
s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
|
||||
_shouldAudit = true;
|
||||
return null;
|
||||
|
||||
@ -25,7 +25,6 @@ import java.util.Objects;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.nuage.vsp.acs.client.api.model.NuageVspUser;
|
||||
import net.nuage.vsp.acs.client.api.model.VspHost;
|
||||
import net.nuage.vsp.acs.client.common.NuageVspApiVersion;
|
||||
@ -34,6 +33,8 @@ import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import com.cloud.util.NuageVspUtil;
|
||||
|
||||
public class NuageVspResourceConfiguration {
|
||||
@ -265,7 +266,7 @@ public class NuageVspResourceConfiguration {
|
||||
verifyNotEmpty("API version", _apiVersion);
|
||||
|
||||
try {
|
||||
new NuageVspApiVersion(_apiVersion);
|
||||
NuageVspApiVersion.fromString(_apiVersion);
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new ConfigurationException("Incorrect API version");
|
||||
}
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.network.resource;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import com.cloud.utils.mgmt.ManagementBean;
|
||||
|
||||
/**
|
||||
* Created by sgoeminn on 1/24/17.
|
||||
*/
|
||||
public interface VspStatisticsMBean extends ManagementBean {
|
||||
|
||||
/**
|
||||
* Returns the global count of all the VSD calls since start up
|
||||
* @return
|
||||
*/
|
||||
long getVSDStatistics();
|
||||
|
||||
/**
|
||||
* Returns the count of all the vsd calls where the entityType is equal to the entity
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
long getVsdStatisticsByEntityType(String entity);
|
||||
|
||||
/**
|
||||
* Returns the count of all the vsd calls where the requestType is equal to the requestType
|
||||
* @param requestType
|
||||
* @return
|
||||
*/
|
||||
long getVsdStatisticsByRequestType(String requestType);
|
||||
|
||||
/**
|
||||
* Returns the count of all the vsd calls where the EntityType is equal to the entity
|
||||
* and the RequestType is equal to the requestType string.
|
||||
* @param entity
|
||||
* @param requestType
|
||||
* @return
|
||||
*/
|
||||
long getVsdStatisticsByEntityAndRequestType(String entity, String requestType);
|
||||
|
||||
/**
|
||||
* Returns the count of all VSD calls with EntityType entity and RequestType type
|
||||
* @return
|
||||
*/
|
||||
Map<String, Map<String, AtomicLong>> getVsdStatisticsReport();
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.network.resource;
|
||||
|
||||
import javax.management.StandardMBean;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Created by sgoeminn on 1/24/17.
|
||||
*/
|
||||
public class VspStatisticsMBeanImpl extends StandardMBean implements VspStatisticsMBean{
|
||||
private VspStatisticsMBean _delegate;
|
||||
|
||||
public VspStatisticsMBeanImpl(VspStatisticsMBean nuageVspResource) {
|
||||
super(VspStatisticsMBean.class, false);
|
||||
_delegate = nuageVspResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVSDStatistics() {
|
||||
return _delegate.getVSDStatistics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByEntityType(String entity) {
|
||||
return _delegate.getVsdStatisticsByEntityType(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByRequestType(String requestType) {
|
||||
return _delegate.getVsdStatisticsByRequestType(requestType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVsdStatisticsByEntityAndRequestType(String entity, String requestType) {
|
||||
return _delegate.getVsdStatisticsByEntityAndRequestType(entity, requestType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, AtomicLong>> getVsdStatisticsReport() {
|
||||
return _delegate.getVsdStatisticsReport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _delegate.getName();
|
||||
}
|
||||
}
|
||||
@ -21,22 +21,27 @@ package com.cloud.network.vsp.resource.wrapper;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.NuageVspGuruClient;
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
import net.nuage.vsp.acs.client.exception.NuageVspException;
|
||||
|
||||
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
|
||||
import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
|
||||
import com.cloud.network.resource.NuageVspResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.resource.ResourceWrapper;
|
||||
|
||||
@ResourceWrapper(handles = ImplementNetworkVspCommand.class)
|
||||
public final class NuageVspGuruImplementNetworkCommandWrapper extends NuageVspCommandWrapper<ImplementNetworkVspCommand> {
|
||||
public final class NuageVspGuruImplementNetworkCommandWrapper extends CommandWrapper<ImplementNetworkVspCommand, ImplementNetworkVspAnswer, NuageVspResource> {
|
||||
|
||||
@Override public boolean executeNuageVspCommand(ImplementNetworkVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException {
|
||||
nuageVspResource.getNuageVspGuruClient().implement(cmd.getNetwork(), cmd.getDhcpOption());
|
||||
return true;
|
||||
@Override
|
||||
public ImplementNetworkVspAnswer execute(ImplementNetworkVspCommand command, NuageVspResource serverResource) {
|
||||
try {
|
||||
NuageVspGuruClient client = serverResource.getNuageVspGuruClient();
|
||||
NetworkRelatedVsdIds networkRelatedVsdIds = client.implement(command.getNetwork(), command.getDhcpOption());
|
||||
return new ImplementNetworkVspAnswer(command, networkRelatedVsdIds);
|
||||
} catch (ConfigurationException | NuageVspException e) {
|
||||
return new ImplementNetworkVspAnswer(command, e);
|
||||
}
|
||||
|
||||
@Override public StringBuilder fillDetail(StringBuilder stringBuilder, ImplementNetworkVspCommand command) {
|
||||
return stringBuilder.append("Created network mapping to ").append(command.getNetwork().getName());
|
||||
}
|
||||
|
||||
}
|
||||
@ -25,14 +25,32 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAddressRange;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
import net.nuage.vsp.acs.client.common.model.Pair;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.dc.VlanVO;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
@ -65,24 +83,12 @@ import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||
import com.cloud.vm.dao.NicSecondaryIpVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAddressRange;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
import net.nuage.vsp.acs.client.common.model.Pair;
|
||||
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
||||
public class NuageVspEntityBuilder {
|
||||
private static final Logger s_logger = Logger.getLogger(NuageVspEntityBuilder.class);
|
||||
@ -112,10 +118,16 @@ public class NuageVspEntityBuilder {
|
||||
@Inject
|
||||
NetworkDetailsDao _networkDetailsDao;
|
||||
@Inject
|
||||
VpcDetailsDao _vpcDetailsDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmInstanceDao;
|
||||
@Inject
|
||||
NuageVspManager _nuageVspManager;
|
||||
@Inject
|
||||
NicDao _nicDao;
|
||||
@Inject
|
||||
NicSecondaryIpDao _nicSecondaryIpDao;
|
||||
@Inject
|
||||
NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
|
||||
|
||||
|
||||
@ -151,6 +163,7 @@ public class NuageVspEntityBuilder {
|
||||
return buildVspNetwork(network.getDomainId(), network);
|
||||
}
|
||||
|
||||
//TODO:Sigert implement caching in this function. retrieve data
|
||||
public VspNetwork buildVspNetwork(long domainId, Network network) {
|
||||
VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder()
|
||||
.id(network.getId())
|
||||
@ -171,31 +184,60 @@ public class NuageVspEntityBuilder {
|
||||
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy()).publicAccess(networkOffering.getSupportsPublicAccess());
|
||||
|
||||
Map<String, String> networkDetails = _networkDetailsDao.listDetailsKeyPairs(network.getId(), false);
|
||||
String vsdSubnetId = null;
|
||||
String vsdZoneId = null;
|
||||
String vsdDomainId = null;
|
||||
|
||||
if (MapUtils.isNotEmpty(networkDetails)) {
|
||||
vsdSubnetId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID);
|
||||
}
|
||||
|
||||
if (network.getVpcId() != null) {
|
||||
VpcVO vpc = _vpcDao.findById(network.getVpcId());
|
||||
long vpcId = network.getVpcId();
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
vspNetworkBuilder.vpcUuid(vpc.getUuid())
|
||||
.vpcName(vpc.getName())
|
||||
.networkType(VspNetwork.NetworkType.Vpc);
|
||||
Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
|
||||
if (MapUtils.isNotEmpty(vpcDetails)) {
|
||||
vsdDomainId = vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
|
||||
vsdZoneId = vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (MapUtils.isNotEmpty(networkDetails)) {
|
||||
vsdDomainId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
|
||||
vsdZoneId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
|
||||
}
|
||||
|
||||
if (networkOffering.getGuestType() == Network.GuestType.Shared) {
|
||||
List<VlanVO> vlans = _vlanDao.listVlansByNetworkIdIncludingRemoved(network.getId());
|
||||
List<VspAddressRange> vspAddressRanges = Lists.transform(vlans, new Function<VlanVO, VspAddressRange>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public VspAddressRange apply(VlanVO vlanVO) {
|
||||
return new VspAddressRange.Builder().gateway(vlanVO.getVlanGateway()).netmask(vlanVO.getVlanNetmask()).build();
|
||||
}
|
||||
});
|
||||
|
||||
vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared).addressRanges(vspAddressRanges);
|
||||
List<VspAddressRange> vspAddressRanges =
|
||||
vlans.stream()
|
||||
.map(vlan -> new VspAddressRange.Builder().gateway(vlan.getVlanGateway()).netmask(vlan.getVlanNetmask()).build())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared)
|
||||
.addressRanges(vspAddressRanges);
|
||||
} else if (_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.SourceNat)
|
||||
|| _networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.StaticNat)) {
|
||||
vspNetworkBuilder.networkType(VspNetwork.NetworkType.L3);
|
||||
} else {
|
||||
vspNetworkBuilder.networkType(VspNetwork.NetworkType.L2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NetworkRelatedVsdIds networkRelatedVsdIds = new NetworkRelatedVsdIds.Builder()
|
||||
.vsdDomainId(vsdDomainId)
|
||||
.vsdSubnetId(vsdSubnetId)
|
||||
.vsdZoneId(vsdZoneId)
|
||||
.build();
|
||||
vspNetworkBuilder.networkRelatedVsdIds(networkRelatedVsdIds);
|
||||
|
||||
boolean firewallServiceSupported = _networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.Firewall);
|
||||
vspNetworkBuilder.firewallServiceSupported(firewallServiceSupported);
|
||||
|
||||
@ -225,15 +267,10 @@ public class NuageVspEntityBuilder {
|
||||
public VspNetwork updateVspNetworkByPublicIp(VspNetwork vspNetwork, Network network, String publicIp) {
|
||||
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
|
||||
final long ip = NetUtils.ip2Long(publicIp);
|
||||
VlanVO matchingVlan = Iterables.find(vlans, new Predicate<VlanVO>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable VlanVO vlan) {
|
||||
Pair<String, String> ipAddressRange = getIpAddressRange(vlan);
|
||||
long startIp = NetUtils.ip2Long(ipAddressRange.getLeft());
|
||||
long endIp = NetUtils.ip2Long(ipAddressRange.getRight());
|
||||
return startIp <= ip && ip <= endIp;
|
||||
}
|
||||
});
|
||||
VlanVO matchingVlan = vlans.stream()
|
||||
.filter(vlan -> isVlanContainingIp(vlan, ip))
|
||||
.findFirst()
|
||||
.get();
|
||||
|
||||
return new VspNetwork.Builder().fromObject(vspNetwork)
|
||||
.gateway(matchingVlan.getVlanGateway())
|
||||
@ -241,6 +278,13 @@ public class NuageVspEntityBuilder {
|
||||
.build();
|
||||
}
|
||||
|
||||
private boolean isVlanContainingIp(Vlan vlan, long ip) {
|
||||
Pair<String, String> ipAddressRange = getIpAddressRange(vlan);
|
||||
long startIp = NetUtils.ip2Long(ipAddressRange.getLeft());
|
||||
long endIp = NetUtils.ip2Long(ipAddressRange.getRight());
|
||||
return startIp <= ip && ip <= endIp;
|
||||
}
|
||||
|
||||
private List<Pair<String, String>> getSharedIpAddressRanges(long networkId) {
|
||||
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
|
||||
List<Pair<String, String>> ipAddressRanges = Lists.newArrayList();
|
||||
@ -326,30 +370,8 @@ public class NuageVspEntityBuilder {
|
||||
public VspVm buildVspVm(VirtualMachine vm, Network network) {
|
||||
VspVm.Builder vspVmBuilder = new VspVm.Builder()
|
||||
.uuid(vm.getUuid())
|
||||
.name(vm.getInstanceName());
|
||||
|
||||
switch (vm.getState()) {
|
||||
case Starting:
|
||||
vspVmBuilder.state(VspVm.State.Starting); break;
|
||||
case Running:
|
||||
vspVmBuilder.state(VspVm.State.Running); break;
|
||||
case Stopping:
|
||||
vspVmBuilder.state(VspVm.State.Stopping); break;
|
||||
case Stopped:
|
||||
vspVmBuilder.state(VspVm.State.Stopped); break;
|
||||
case Destroyed:
|
||||
vspVmBuilder.state(VspVm.State.Destroyed); break;
|
||||
case Expunging:
|
||||
vspVmBuilder.state(VspVm.State.Expunging); break;
|
||||
case Migrating:
|
||||
vspVmBuilder.state(VspVm.State.Migrating); break;
|
||||
case Error:
|
||||
vspVmBuilder.state(VspVm.State.Error); break;
|
||||
case Shutdowned:
|
||||
vspVmBuilder.state(VspVm.State.Shutdowned); break;
|
||||
default:
|
||||
vspVmBuilder.state(VspVm.State.Unknown);
|
||||
}
|
||||
.name(vm.getInstanceName())
|
||||
.state(getEnumValue(vm.getState(), VspVm.State.Unknown));
|
||||
|
||||
boolean isDomainRouter = vm.getType().equals(VirtualMachine.Type.DomainRouter);
|
||||
vspVmBuilder.domainRouter(isDomainRouter);
|
||||
@ -363,20 +385,28 @@ public class NuageVspEntityBuilder {
|
||||
}
|
||||
|
||||
public VspNic buildVspNic(String nicUuid, NicProfile nicProfile) {
|
||||
return buildVspNic(nicUuid, nicProfile.getMacAddress(), nicProfile.getIPv4Address(), nicProfile.getNetworkId());
|
||||
return buildVspNic(nicUuid, nicProfile.getMacAddress(), nicProfile.getIPv4Address(), nicProfile.getNetworkId(), null);
|
||||
}
|
||||
|
||||
public VspNic buildVspNic(NicVO nic) {
|
||||
return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId());
|
||||
return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), null);
|
||||
}
|
||||
|
||||
private VspNic buildVspNic(String uuid, String macAddress, String ip, long networkId) {
|
||||
public VspNic buildVspNic(NicVO nic, NicSecondaryIpVO nicSecondaryIp) {
|
||||
return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId(), nicSecondaryIp);
|
||||
}
|
||||
|
||||
private VspNic buildVspNic(String uuid, String macAddress, String ip, long networkId, NicSecondaryIpVO nicSecondaryIp) {
|
||||
VspNic.Builder vspNicBuilder = new VspNic.Builder()
|
||||
.uuid(uuid)
|
||||
.macAddress(macAddress)
|
||||
.useStaticIp(true)
|
||||
.ip(ip);
|
||||
|
||||
if (nicSecondaryIp != null) {
|
||||
vspNicBuilder.secondaryIpUuid(nicSecondaryIp.getUuid()).secondaryIpAddress(nicSecondaryIp.getIp4Address());
|
||||
}
|
||||
|
||||
Network network = _networkDao.findById(networkId);
|
||||
NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
|
||||
@ -395,6 +425,10 @@ public class NuageVspEntityBuilder {
|
||||
.vlanNetmask(staticNatVlan.getVlanNetmask())
|
||||
.vlanUnderlay(NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, staticNatVlan));
|
||||
|
||||
if (staticNatIp.getVmIp() != null) {
|
||||
vspStaticNatBuilder.destinationIp(staticNatIp.getVmIp() + "/32");
|
||||
}
|
||||
|
||||
if (vspNic != null) {
|
||||
vspStaticNatBuilder.nic(vspNic);
|
||||
}
|
||||
@ -403,11 +437,24 @@ public class NuageVspEntityBuilder {
|
||||
}
|
||||
|
||||
public VspStaticNat buildVspStaticNat(Boolean forRevoke, IPAddressVO staticNatIp, VlanVO staticNatVlan, NicVO nic) {
|
||||
VspNic vspNic = (nic != null) ?buildVspNic(nic) : null;
|
||||
NicSecondaryIpVO nicSecondaryIp = null;
|
||||
|
||||
if (nic == null && staticNatIp.getAssociatedWithVmId() != null && staticNatIp.getVmIp() != null) {
|
||||
nicSecondaryIp = _nicSecondaryIpDao.findByIp4AddressAndInstanceId(staticNatIp.getAssociatedWithVmId(), staticNatIp.getVmIp());
|
||||
if (nicSecondaryIp != null) {
|
||||
nic = _nicDao.findById(nicSecondaryIp.getNicId());
|
||||
}
|
||||
}
|
||||
|
||||
VspNic vspNic = (nic != null) ? buildVspNic(nic, nicSecondaryIp) : null;
|
||||
return buildVspStaticNat(forRevoke, staticNatIp, staticNatVlan, vspNic);
|
||||
}
|
||||
|
||||
public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network) {
|
||||
return buildVspAclRule(firewallRule, network, null);
|
||||
}
|
||||
|
||||
public VspAclRule buildVspAclRule(FirewallRule firewallRule, Network network, IPAddressVO staticNat) {
|
||||
VspAclRule.Builder vspAclRuleBuilder = new VspAclRule.Builder()
|
||||
.uuid(firewallRule.getUuid())
|
||||
.protocol(firewallRule.getProtocol())
|
||||
@ -415,35 +462,25 @@ public class NuageVspEntityBuilder {
|
||||
.endPort(firewallRule.getSourcePortEnd())
|
||||
.sourceCidrList(firewallRule.getSourceCidrList())
|
||||
.priority(-1)
|
||||
.type(VspAclRule.ACLType.Firewall);
|
||||
|
||||
switch (firewallRule.getState()) {
|
||||
case Active:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Active); break;
|
||||
case Add:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Add); break;
|
||||
case Revoke:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Revoke);
|
||||
}
|
||||
|
||||
switch (firewallRule.getTrafficType()) {
|
||||
case Ingress:
|
||||
vspAclRuleBuilder.trafficType(VspAclRule.ACLTrafficType.Ingress); break;
|
||||
case Egress:
|
||||
vspAclRuleBuilder.trafficType(VspAclRule.ACLTrafficType.Egress);
|
||||
}
|
||||
.type(VspAclRule.ACLType.Firewall)
|
||||
.state(getEnumValue(firewallRule.getState(), VspAclRule.ACLState.class))
|
||||
.trafficType(getEnumValue(firewallRule.getTrafficType(), VspAclRule.ACLTrafficType.class));
|
||||
|
||||
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
|
||||
if (firewallRule.getTrafficType() == FirewallRule.TrafficType.Egress && networkOffering.getEgressDefaultPolicy()) {
|
||||
vspAclRuleBuilder.action(VspAclRule.ACLAction.Deny);
|
||||
vspAclRuleBuilder.deny();
|
||||
} else {
|
||||
vspAclRuleBuilder.action(VspAclRule.ACLAction.Allow);
|
||||
vspAclRuleBuilder.allow();
|
||||
}
|
||||
|
||||
if (firewallRule.getSourceIpAddressId() != null) {
|
||||
IPAddressVO ipAddress = _ipAddressDao.findById(firewallRule.getSourceIpAddressId());
|
||||
if (ipAddress != null) {
|
||||
vspAclRuleBuilder.sourceIpAddress(ipAddress.getVmIp() + "/32");
|
||||
if (staticNat == null && firewallRule.getSourceIpAddressId() != null) {
|
||||
IPAddressVO staticNatIp = _ipAddressDao.findById(firewallRule.getSourceIpAddressId());
|
||||
|
||||
if (staticNatIp != null) {
|
||||
VlanVO staticNatVlan = _vlanDao.findById(staticNatIp.getVlanId());
|
||||
NicVO nic = _nicDao.findByIp4AddressAndNetworkId(staticNatIp.getVmIp(), staticNatIp.getAssociatedWithNetworkId());
|
||||
|
||||
vspAclRuleBuilder.staticNat(buildVspStaticNat(null, staticNatIp, staticNatVlan, nic));
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,7 +488,7 @@ public class NuageVspEntityBuilder {
|
||||
}
|
||||
|
||||
public VspAclRule buildVspAclRule(NetworkACLItem networkAcl) {
|
||||
VspAclRule.Builder vspAclRuleBuilder = new VspAclRule.Builder()
|
||||
return new VspAclRule.Builder()
|
||||
.uuid(networkAcl.getUuid())
|
||||
.protocol(networkAcl.getProtocol())
|
||||
.startPort(networkAcl.getSourcePortStart())
|
||||
@ -459,32 +496,11 @@ public class NuageVspEntityBuilder {
|
||||
.sourceIpAddress(null)
|
||||
.sourceCidrList(networkAcl.getSourceCidrList())
|
||||
.priority(networkAcl.getNumber())
|
||||
.type(VspAclRule.ACLType.NetworkACL);
|
||||
|
||||
switch (networkAcl.getState()) {
|
||||
case Active:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Active); break;
|
||||
case Add:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Add); break;
|
||||
case Revoke:
|
||||
vspAclRuleBuilder.state(VspAclRule.ACLState.Revoke);
|
||||
}
|
||||
|
||||
switch (networkAcl.getTrafficType()) {
|
||||
case Ingress:
|
||||
vspAclRuleBuilder.trafficType(VspAclRule.ACLTrafficType.Ingress); break;
|
||||
case Egress:
|
||||
vspAclRuleBuilder.trafficType(VspAclRule.ACLTrafficType.Egress);
|
||||
}
|
||||
|
||||
switch (networkAcl.getAction()) {
|
||||
case Allow:
|
||||
vspAclRuleBuilder.action(VspAclRule.ACLAction.Allow); break;
|
||||
case Deny:
|
||||
vspAclRuleBuilder.action(VspAclRule.ACLAction.Deny);
|
||||
}
|
||||
|
||||
return vspAclRuleBuilder.build();
|
||||
.type(VspAclRule.ACLType.NetworkACL)
|
||||
.state(getEnumValue(networkAcl.getState(), VspAclRule.ACLState.class))
|
||||
.trafficType(getEnumValue(networkAcl.getTrafficType(), VspAclRule.ACLTrafficType.class))
|
||||
.action(getEnumValue(networkAcl.getAction(), VspAclRule.ACLAction.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
/** Build VspDhcpVMOption to put on the VM interface */
|
||||
|
||||
@ -21,6 +21,7 @@ package com.cloud;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption;
|
||||
@ -113,6 +114,16 @@ public class NuageTest {
|
||||
.cidr("networkCidr")
|
||||
.gateway("networkGateway")
|
||||
.virtualRouterIp("virtualRouterIp")
|
||||
.networkRelatedVsdIds(buildNetworkRelatedIds())
|
||||
.build();
|
||||
}
|
||||
|
||||
protected NetworkRelatedVsdIds buildNetworkRelatedIds() {
|
||||
return new NetworkRelatedVsdIds.Builder()
|
||||
.vsdZoneId("vsdZoneId")
|
||||
.vsdDomainId("vsdDomainId")
|
||||
.vsdEnterpriseId("vsdEnterpriseId")
|
||||
.vsdSubnetId("vsdSubnetId")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
@ -37,6 +38,8 @@ import com.cloud.NuageTest;
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
|
||||
import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
@ -142,6 +145,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(_agentManager.easySend(eq(NETWORK_ID), any(ImplementNetworkVspCommand.class))).thenReturn(new ImplementNetworkVspAnswer(null, new NetworkRelatedVsdIds.Builder().build()));
|
||||
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
|
||||
|
||||
final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
|
||||
|
||||
@ -58,6 +58,7 @@ 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.ImplementNetworkVspAnswer;
|
||||
import com.cloud.host.Host;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@ -152,7 +153,7 @@ public class NuageVspResourceTest extends NuageTest {
|
||||
VspNetwork vspNetwork = buildVspNetwork();
|
||||
VspDhcpDomainOption vspDhcpOptions = buildspDhcpDomainOption();
|
||||
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpOptions);
|
||||
com.cloud.agent.api.Answer implNtwkAns = _resource.executeRequest(cmd);
|
||||
ImplementNetworkVspAnswer implNtwkAns = (ImplementNetworkVspAnswer)_resource.executeRequest(cmd);
|
||||
assertTrue(implNtwkAns.getResult());
|
||||
verify(_mockNuageVspGuruClient).implement(vspNetwork, vspDhcpOptions);
|
||||
}
|
||||
|
||||
@ -19,17 +19,20 @@
|
||||
|
||||
package com.cloud.util;
|
||||
|
||||
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;
|
||||
import net.nuage.vsp.acs.client.api.model.Protocol;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
|
||||
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import com.cloud.NuageTest;
|
||||
import com.cloud.dc.VlanDetailsVO;
|
||||
import com.cloud.dc.VlanVO;
|
||||
@ -57,15 +60,15 @@ import com.cloud.utils.net.Ip;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
||||
import net.nuage.vsp.acs.client.api.model.Protocol;
|
||||
import net.nuage.vsp.acs.client.api.model.VspAclRule;
|
||||
import net.nuage.vsp.acs.client.api.model.VspDomain;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNetwork;
|
||||
import net.nuage.vsp.acs.client.api.model.VspNic;
|
||||
import net.nuage.vsp.acs.client.api.model.VspStaticNat;
|
||||
import net.nuage.vsp.acs.client.api.model.VspVm;
|
||||
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;
|
||||
|
||||
public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
|
||||
@ -76,8 +79,12 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
private static final long L2_NETWORK_OFFERING_ID = 3L;
|
||||
private static final long VPC_ID = 1L;
|
||||
private static final long SOURCE_IP_ADDRESS_ID = 1L;
|
||||
private static final long VM_ID = 4L;
|
||||
private static final long VLAN_ID = 5L;
|
||||
public static final String VM_IP = "192.168.0.24";
|
||||
|
||||
private VpcDao _vpcDao = mock(VpcDao.class);
|
||||
private VpcDetailsDao _vpcDetailsDao = mock(VpcDetailsDao.class);
|
||||
private DomainDao _domainDao = mock(DomainDao.class);
|
||||
private AccountDao _accountDao = mock(AccountDao.class);
|
||||
private NetworkDao _networkDao = mock(NetworkDao.class);
|
||||
@ -87,6 +94,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
private VlanDetailsDao _vlanDetailsDao = mock(VlanDetailsDao.class);
|
||||
private IPAddressDao _ipAddressDao = mock(IPAddressDao.class);
|
||||
private NetworkDetailsDao _networkDetailsDao = mock(NetworkDetailsDao.class);
|
||||
private NicDao _nicDao = mock(NicDao.class);
|
||||
private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder();
|
||||
|
||||
private DomainVO _mockedDomain = mock(DomainVO.class);
|
||||
@ -115,6 +123,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
super.setUp();
|
||||
|
||||
_nuageVspEntityBuilder._vpcDao = _vpcDao;
|
||||
_nuageVspEntityBuilder._vpcDetailsDao = _vpcDetailsDao;
|
||||
_nuageVspEntityBuilder._domainDao = _domainDao;
|
||||
_nuageVspEntityBuilder._accountDao = _accountDao;
|
||||
_nuageVspEntityBuilder._networkDao = _networkDao;
|
||||
@ -126,6 +135,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
_nuageVspEntityBuilder._ipAddressDao = _ipAddressDao;
|
||||
_nuageVspEntityBuilder._networkModel = _networkModel;
|
||||
_nuageVspEntityBuilder._networkDetailsDao = _networkDetailsDao;
|
||||
_nuageVspEntityBuilder._nicDao = _nicDao;
|
||||
|
||||
setUpMockedDomain();
|
||||
setUpMockedAccount();
|
||||
@ -208,12 +218,15 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildVspAclRule() {
|
||||
public void testBuildVspAclRuleAcl() {
|
||||
VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedNetworkAclItem);
|
||||
validateVspAclRule(vspAclRule, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildVspAclRuleFirewall() {
|
||||
VspAclRule vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedFirewallRule, _mockedNetwork);
|
||||
validateVspAclRule(vspAclRule, true);
|
||||
|
||||
vspAclRule = _nuageVspEntityBuilder.buildVspAclRule(_mockedNetworkAclItem);
|
||||
validateVspAclRule(vspAclRule, false);
|
||||
}
|
||||
|
||||
private void validateVspDomain(VspDomain vspDomain) {
|
||||
@ -229,6 +242,7 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
assertEquals("networkName", vspNetwork.getName());
|
||||
assertNotNull(vspNetwork.getVspDomain());
|
||||
validateVspDomain(vspNetwork.getVspDomain());
|
||||
|
||||
assertEquals("accountName", vspNetwork.getAccountName());
|
||||
assertEquals("accountUuid", vspNetwork.getAccountUuid());
|
||||
|
||||
@ -262,13 +276,14 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
assertEquals("nicUuid", vspNic.getUuid());
|
||||
assertEquals("macAddress", vspNic.getMacAddress());
|
||||
assertEquals(true, vspNic.getUseStaticIp());
|
||||
assertEquals("10.10.10.2", vspNic.getIp());
|
||||
assertEquals("192.168.0.24", vspNic.getIp());
|
||||
}
|
||||
|
||||
private void validateVspStaticNat(VspStaticNat vspStaticNat, Boolean forRevoke) {
|
||||
assertEquals("staticNatIpUuid", vspStaticNat.getIpUuid());
|
||||
assertEquals("10.10.10.2", vspStaticNat.getIpAddress());
|
||||
assertEquals(forRevoke, vspStaticNat.getRevoke());
|
||||
assertEquals(VspStaticNat.State.Allocated, vspStaticNat.getState());
|
||||
assertEquals(true, vspStaticNat.getOneToOneNat());
|
||||
assertEquals("staticNatVlanUuid", vspStaticNat.getVlanUuid());
|
||||
assertEquals("10.10.10.1", vspStaticNat.getVlanGateway());
|
||||
@ -286,10 +301,13 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
|
||||
if (isFirewall) {
|
||||
assertEquals(VspAclRule.ACLType.Firewall, vspAclRule.getType());
|
||||
assertEquals("192.168.0.24/32", vspAclRule.getSourceIpAddress());
|
||||
final VspStaticNat staticNat = vspAclRule.getStaticNat();
|
||||
assertNotNull(staticNat);
|
||||
assertEquals("192.168.0.24/32", staticNat.getDestinationIp());
|
||||
assertEquals(VspAclRule.ACLAction.Deny, vspAclRule.getAction());
|
||||
} else {
|
||||
assertEquals(VspAclRule.ACLType.NetworkACL, vspAclRule.getType());
|
||||
assertNull(vspAclRule.getStaticNat());
|
||||
assertNull(vspAclRule.getSourceIpAddress());
|
||||
assertEquals(VspAclRule.ACLAction.Allow, vspAclRule.getAction());
|
||||
}
|
||||
@ -345,14 +363,14 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
|
||||
private void setUpMockedNicProfile() {
|
||||
when(_mockedNicProfile.getMacAddress()).thenReturn("macAddress");
|
||||
when(_mockedNicProfile.getIPv4Address()).thenReturn("10.10.10.2");
|
||||
when(_mockedNicProfile.getIPv4Address()).thenReturn(VM_IP);
|
||||
when(_mockedNicProfile.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
}
|
||||
|
||||
private void setUpMockedNic() {
|
||||
when(_mockedNic.getUuid()).thenReturn("nicUuid");
|
||||
when(_mockedNic.getMacAddress()).thenReturn("macAddress");
|
||||
when(_mockedNic.getIPv4Address()).thenReturn("10.10.10.2");
|
||||
when(_mockedNic.getIPv4Address()).thenReturn(VM_IP);
|
||||
when(_mockedNic.getNetworkId()).thenReturn(NETWORK_ID);
|
||||
}
|
||||
|
||||
@ -360,8 +378,11 @@ public class NuageVspEntityBuilderTest extends NuageTest {
|
||||
when(_mockedStaticNatIp.getUuid()).thenReturn("staticNatIpUuid");
|
||||
when(_mockedStaticNatIp.getAddress()).thenReturn(new Ip("10.10.10.2"));
|
||||
when(_mockedStaticNatIp.isOneToOneNat()).thenReturn(true);
|
||||
when(_mockedStaticNatIp.getVmIp()).thenReturn("192.168.0.24");
|
||||
when(_mockedStaticNatIp.getVmIp()).thenReturn(VM_IP);
|
||||
when(_mockedStaticNatIp.getAssociatedWithNetworkId()).thenReturn(NETWORK_ID);
|
||||
when(_mockedStaticNatIp.getAssociatedWithVmId()).thenReturn(VM_ID);
|
||||
when(_mockedStaticNatIp.getState()).thenReturn(IpAddress.State.Allocated);
|
||||
when(_mockedStaticNatIp.getVlanId()).thenReturn(VLAN_ID);
|
||||
}
|
||||
|
||||
private void setUpMockedStaticNatVlan() {
|
||||
@ -410,8 +431,11 @@ 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(_vlanDao.findById(VLAN_ID)).thenReturn(_mockedVlan);
|
||||
when(_vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(_mockedVlanDetail);
|
||||
when(_vpcDao.findById(VPC_ID)).thenReturn(_mockedVpc);
|
||||
when(_ipAddressDao.findById(SOURCE_IP_ADDRESS_ID)).thenReturn(_mockedStaticNatIp);
|
||||
when(_vpcDetailsDao.listDetailsKeyPairs(VPC_ID)).thenReturn(null);
|
||||
when(_nicDao.findByIp4AddressAndNetworkId("192.168.0.24", NETWORK_ID)).thenReturn(_mockedNic);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ import socket
|
||||
import sys
|
||||
import time
|
||||
from retry import retry
|
||||
from nuage_vsp_statistics import VsdDataCollector
|
||||
|
||||
|
||||
class needscleanup(object):
|
||||
|
||||
2050
test/integration/plugins/nuagevsp/nuage_test_data.py
Normal file
2050
test/integration/plugins/nuagevsp/nuage_test_data.py
Normal file
File diff suppressed because it is too large
Load Diff
202
test/integration/plugins/nuagevsp/nuage_vsp_statistics.py
Normal file
202
test/integration/plugins/nuagevsp/nuage_vsp_statistics.py
Normal file
@ -0,0 +1,202 @@
|
||||
# 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.
|
||||
|
||||
import jpype
|
||||
from jpype import *
|
||||
from jpype import java
|
||||
from jpype import javax
|
||||
|
||||
J_STRING = "java.lang.String"
|
||||
|
||||
|
||||
class VsdDataCollector:
|
||||
def __init__(self, name, host="localhost", port=1099, debug=False,
|
||||
output_channel=None):
|
||||
self.jmx = ConnectionJmx(host, port, debug, output_channel)
|
||||
self.jmx.create_management_object(name=name)
|
||||
self.saved_stats = None
|
||||
self.saved_vsd_calls = 0
|
||||
|
||||
def start_test(self):
|
||||
self.saved_stats = self.jmx.get_attribute("VsdStatisticsReport")
|
||||
self.saved_vsd_calls = self.jmx.get_attribute("VSDStatistics")
|
||||
return
|
||||
|
||||
def end_test(self):
|
||||
self.jmx.print_rapport(old_stats=self.saved_stats,
|
||||
old_vsd_count=self.saved_vsd_calls)
|
||||
return
|
||||
|
||||
|
||||
class ConnectionJmx:
|
||||
|
||||
def __init__(self, host="localhost", port=1099, debug=False,
|
||||
output_channel=None):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.url = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % (host, port)
|
||||
self.debug = debug
|
||||
self.mbean = None
|
||||
self.output_channel = output_channel
|
||||
jpype.startJVM(jpype.get_default_jvm_path())
|
||||
if debug:
|
||||
self.__print_to_ouput_channel("JVM loaded")
|
||||
self.__print_to_ouput_channel(jpype.get_default_jvm_path())
|
||||
|
||||
jmx_url = javax.management.remote.JMXServiceURL(self.url)
|
||||
jmx_soc = javax.management.remote.JMXConnectorFactory.connect(
|
||||
jmx_url, java.util.HashMap())
|
||||
self.connection = jmx_soc.getMBeanServerConnection()
|
||||
if self.debug:
|
||||
self.__print_to_ouput_channel("Connection successful")
|
||||
|
||||
def __print_to_ouput_channel(self, text):
|
||||
if self.output_channel:
|
||||
self.output_channel.debug(text)
|
||||
else:
|
||||
print text
|
||||
|
||||
def create_management_object(self, domain="com.cloud",
|
||||
type="NuageVspResource",
|
||||
name="Nuage VSD - 0.0.0.0"):
|
||||
if name is not None:
|
||||
object_name = domain + ":type=" + type + ", name=" + name
|
||||
else:
|
||||
object_name = domain + ":" + type
|
||||
|
||||
if self.debug:
|
||||
self.__print_to_ouput_channel(object_name)
|
||||
|
||||
self.mbean = javax.management.ObjectName(object_name)
|
||||
return self.mbean
|
||||
|
||||
def get_vsd_statistics_by_request_and_entity_type(self,
|
||||
entity_type,
|
||||
request_type,
|
||||
mbean=None):
|
||||
self._get_stats_by_entity_or_request_type(
|
||||
mbean, [[entity_type, request_type]],
|
||||
"getVsdStatisticsByEntityType")
|
||||
|
||||
def _jStringArray(self, elements):
|
||||
return jpype.JArray(java.lang.String)(elements)
|
||||
|
||||
def get_vsd_statistics_by_request_type(self, request_type, mbean=None):
|
||||
return self._get_stats_by_entity_or_request_type(
|
||||
mbean, [request_type], "getVsdStatisticsByRequestType")
|
||||
|
||||
def get_vsd_statistics_by_entity_type(self, entity_type, mbean=None):
|
||||
return self._get_stats_by_entity_or_request_type(
|
||||
mbean, [entity_type], "getVsdStatisticsByEntityType")
|
||||
|
||||
def _get_stats_by_entity_or_request_type(self, vars, method, mbean=None):
|
||||
if not mbean:
|
||||
mbean = self.mbean
|
||||
jarray = self._jStringArray(vars)
|
||||
signature = self._jStringArray([J_STRING for _ in vars])
|
||||
result = self.connection.invoke(mbean, method, jarray, signature)
|
||||
if self.debug:
|
||||
self.__print_to_ouput_channel(vars + ": " + str(result))
|
||||
return result
|
||||
|
||||
def get_attribute(self, attribute, mbean=None):
|
||||
if not mbean:
|
||||
mbean = self.mbean
|
||||
|
||||
result = self.connection.getAttribute(mbean, attribute)
|
||||
if self.debug:
|
||||
self.__print_to_ouput_channel("Attribute " + attribute + ": " +
|
||||
str(result))
|
||||
return result
|
||||
|
||||
def print_rapport(self, mbean=None, old_stats=None, old_vsd_count=0):
|
||||
if not mbean:
|
||||
mbean = self.mbean
|
||||
stat = self.get_attribute("VsdStatisticsReport", mbean)
|
||||
number_of_vsd_calls = int(str(self.get_attribute("VSDStatistics",
|
||||
mbean)))
|
||||
number_of_vsd_calls = number_of_vsd_calls - int(str(old_vsd_count))
|
||||
|
||||
self.__print_to_ouput_channel("\n================"
|
||||
"RAPPORT:"
|
||||
"================\n")
|
||||
self.__print_to_ouput_channel("Total VSD calls: " +
|
||||
str(number_of_vsd_calls))
|
||||
self.__print_to_ouput_channel("For each Entity:\n")
|
||||
self.__print_total_for_entity(stat, old_stats)
|
||||
self.__print_to_ouput_channel("\nFor each Request:\n")
|
||||
self.__print_total_per_request(stat, old_stats)
|
||||
self.__print_to_ouput_channel("\nCombined:\n")
|
||||
self.__print_total_per_entity_and_request(stat, old_stats)
|
||||
self.__print_to_ouput_channel("\n============="
|
||||
"END OF RAPPORT"
|
||||
"=============")
|
||||
|
||||
def __print_total_per_request(self, stat, old_stat=None):
|
||||
data = dict()
|
||||
|
||||
entries = ((entry.getKey(), entry.getValue().get())
|
||||
for requestmap in stat.values()
|
||||
for entry in requestmap.entrySet())
|
||||
|
||||
for request, value in entries:
|
||||
if request in data:
|
||||
data[request] += value
|
||||
else:
|
||||
data[request] = value
|
||||
|
||||
if old_stat:
|
||||
old_entries = ((entry.getKey(), entry.getValue().get())
|
||||
for requestmap in old_stat.values()
|
||||
for entry in requestmap.entrySet())
|
||||
|
||||
for request, value in old_entries:
|
||||
if request in data:
|
||||
data[request] -= value
|
||||
else:
|
||||
data[request] = 0
|
||||
|
||||
for key, value in data.iteritems():
|
||||
self.__print_to_ouput_channel(" " + str(key) + ": " + str(value))
|
||||
|
||||
def __print_total_per_entity_and_request(self, stat, old_stat=None):
|
||||
for entity in stat:
|
||||
self.__print_to_ouput_channel(entity + ":")
|
||||
for request in stat[entity]:
|
||||
previous = 0
|
||||
if old_stat and old_stat[entity] and old_stat[entity][request]:
|
||||
previous = int(str(old_stat[entity][request]))
|
||||
|
||||
current = int(str(stat[entity][request]))
|
||||
|
||||
self.__print_to_ouput_channel(" " + str(request) + ":" +
|
||||
str(current - previous))
|
||||
self.__print_to_ouput_channel("--------------------"
|
||||
"--------------------")
|
||||
|
||||
def __print_total_for_entity(self, stat, old_stat=None):
|
||||
for entity in stat:
|
||||
total = 0
|
||||
for val in stat[entity]:
|
||||
minus = 0
|
||||
if old_stat and old_stat[entity] and old_stat[entity][val]:
|
||||
minus = int(str(old_stat[entity][val]))
|
||||
total = str(stat[entity][val])
|
||||
|
||||
total = int(total) - minus
|
||||
self.__print_to_ouput_channel(" " + str(entity) +
|
||||
": " + str(total))
|
||||
@ -165,13 +165,14 @@ class TestNuageStaticNat(nuageTestCase):
|
||||
time.sleep(60)
|
||||
tries += 1
|
||||
|
||||
try:
|
||||
if not filename and not headers:
|
||||
if non_default_nic:
|
||||
self.debug("Failed to wget from VM via this NIC as it is not "
|
||||
"the default NIC")
|
||||
self.debug("Failed to wget from VM via this NIC as it "
|
||||
"is not the default NIC")
|
||||
else:
|
||||
self.fail("Failed to wget from VM")
|
||||
|
||||
finally:
|
||||
# Removing Ingress Firewall/Network ACL rule
|
||||
self.debug("Removing the created Ingress Firewall/Network ACL "
|
||||
"rule in the network...")
|
||||
@ -183,9 +184,9 @@ class TestNuageStaticNat(nuageTestCase):
|
||||
self.debug("Ingress Firewall/Network ACL rule successfully "
|
||||
"deleted in VSD")
|
||||
|
||||
self.debug("Successfully verified Static NAT traffic by performing "
|
||||
"wget traffic test with the given Static NAT enabled "
|
||||
"public IP - %s" % public_ip)
|
||||
self.debug("Successfully verified Static NAT traffic by "
|
||||
"performing wget traffic test with the given Static "
|
||||
"NAT enabled public IP - %s" % public_ip)
|
||||
|
||||
# wget_from_internet - From within the given VM (ssh client),
|
||||
# fetches index.html file of an Internet web server, wget www.google.com
|
||||
@ -240,11 +241,12 @@ class TestNuageStaticNat(nuageTestCase):
|
||||
|
||||
# SSH into VM
|
||||
ssh_client = None
|
||||
try:
|
||||
if non_default_nic:
|
||||
with self.assertRaises(Exception):
|
||||
self.ssh_into_VM(vm, public_ip, negative_test=True)
|
||||
self.debug("Can not SSH into the VM via this NIC as it is not the "
|
||||
"default NIC")
|
||||
self.debug("Can not SSH into the VM via this NIC as it is "
|
||||
"not the default NIC")
|
||||
else:
|
||||
ssh_client = self.ssh_into_VM(vm, public_ip)
|
||||
|
||||
@ -253,7 +255,7 @@ class TestNuageStaticNat(nuageTestCase):
|
||||
if ssh_client and self.isInternetConnectivityAvailable:
|
||||
timeout = 100 if negative_test else 300
|
||||
test_result = self.wget_from_Internet(ssh_client, timeout)
|
||||
|
||||
finally:
|
||||
# Removing Ingress Firewall/Network ACL rule
|
||||
self.debug("Removing the created Ingress Firewall/Network ACL "
|
||||
"rule in the network...")
|
||||
@ -1579,7 +1581,7 @@ class TestNuageStaticNat(nuageTestCase):
|
||||
self.verify_vsd_floating_ip(network_2, vm, public_ip_2.ipaddress)
|
||||
|
||||
# Verifying Static NAT traffic
|
||||
with self.assertRaises(Exception):
|
||||
with self.assertRaises(AssertionError):
|
||||
self.verify_StaticNAT_traffic(network_1, public_ip_1)
|
||||
self.debug("Static NAT rule not enabled in this VM NIC")
|
||||
self.verify_StaticNAT_traffic(network_2, public_ip_2)
|
||||
|
||||
@ -57,7 +57,7 @@ setup(name="Marvin",
|
||||
"ipmisim >= 0.7"
|
||||
],
|
||||
extras_require={
|
||||
"nuagevsp": ["libVSD", "PyYAML", "futures", "netaddr", "retries"]
|
||||
"nuagevsp": ["libVSD", "PyYAML", "futures", "netaddr", "retries", "jpype1"]
|
||||
},
|
||||
py_modules=['marvin.marvinPlugin'],
|
||||
zip_safe=False,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user