You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/04/15 19:25:16 UTC
[24/33] Squashed commit of the following:
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e94c7025/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java
new file mode 100755
index 0000000..dff9288
--- /dev/null
+++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoAsa1000vService.java
@@ -0,0 +1,43 @@
+// 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.element;
+
+import java.util.List;
+
+import com.cloud.api.commands.AddCiscoAsa1000vResourceCmd;
+import com.cloud.api.commands.DeleteCiscoAsa1000vResourceCmd;
+import com.cloud.api.commands.ListCiscoAsa1000vResourcesCmd;
+import com.cloud.api.response.CiscoAsa1000vResourceResponse;
+import com.cloud.network.Network;
+import com.cloud.network.cisco.CiscoAsa1000vDevice;
+import com.cloud.network.cisco.CiscoAsa1000vDeviceVO;
+import com.cloud.utils.component.PluggableService;
+
+public interface CiscoAsa1000vService extends PluggableService {
+
+ public CiscoAsa1000vDevice addCiscoAsa1000vResource(AddCiscoAsa1000vResourceCmd cmd);
+
+ public CiscoAsa1000vResourceResponse createCiscoAsa1000vResourceResponse(
+ CiscoAsa1000vDevice ciscoAsa1000vDeviceVO);
+
+ boolean deleteCiscoAsa1000vResource(DeleteCiscoAsa1000vResourceCmd cmd);
+
+ List<CiscoAsa1000vDeviceVO> listCiscoAsa1000vResources(ListCiscoAsa1000vResourcesCmd cmd);
+
+ CiscoAsa1000vDevice assignAsa1000vToNetwork(Network network);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e94c7025/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java
new file mode 100644
index 0000000..443bb40
--- /dev/null
+++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java
@@ -0,0 +1,928 @@
+// 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.element;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AssociateAsaWithLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.CleanupLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.ConfigureNexusVsmForAsaCommand;
+import com.cloud.agent.api.CreateLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalFirewallCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.api.commands.AddCiscoAsa1000vResourceCmd;
+import com.cloud.api.commands.AddCiscoVnmcResourceCmd;
+import com.cloud.api.commands.DeleteCiscoAsa1000vResourceCmd;
+import com.cloud.api.commands.DeleteCiscoVnmcResourceCmd;
+import com.cloud.api.commands.ListCiscoAsa1000vResourcesCmd;
+import com.cloud.api.commands.ListCiscoVnmcResourcesCmd;
+import com.cloud.api.response.CiscoAsa1000vResourceResponse;
+import com.cloud.api.response.CiscoVnmcResourceResponse;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.ClusterVSMMapVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.ClusterVSMMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.DetailVO;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.CiscoNexusVSMDeviceVO;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.cisco.CiscoAsa1000vDevice;
+import com.cloud.network.cisco.CiscoAsa1000vDeviceVO;
+import com.cloud.network.cisco.CiscoVnmcController;
+import com.cloud.network.cisco.CiscoVnmcControllerVO;
+import com.cloud.network.cisco.NetworkAsa1000vMapVO;
+import com.cloud.network.dao.CiscoAsa1000vDao;
+import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
+import com.cloud.network.dao.CiscoVnmcDao;
+import com.cloud.network.dao.NetworkAsa1000vMapDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.network.resource.CiscoVnmcResource;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.PortForwardingRule;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceState;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = NetworkElement.class)
+public class CiscoVnmcElement extends AdapterBase implements SourceNatServiceProvider, FirewallServiceProvider,
+ PortForwardingServiceProvider, IpDeployer, StaticNatServiceProvider, ResourceStateAdapter, NetworkElement,
+ CiscoVnmcElementService, CiscoAsa1000vService {
+ private static final Logger s_logger = Logger.getLogger(CiscoVnmcElement.class);
+ private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
+
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ ConfigurationManager _configMgr;
+ @Inject
+ NetworkManager _networkMgr;
+ @Inject
+ NetworkModel _networkModel;
+
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject
+ HostDetailsDao _hostDetailsDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ NetworkDao _networkDao;
+ @Inject
+ ClusterDao _clusterDao;
+ @Inject
+ VlanDao _vlanDao;
+ @Inject
+ ClusterVSMMapDao _clusterVsmMapDao;
+ @Inject
+ CiscoNexusVSMDeviceDao _vsmDeviceDao;
+ @Inject
+ CiscoVnmcDao _ciscoVnmcDao;
+ @Inject
+ CiscoAsa1000vDao _ciscoAsa1000vDao;
+ @Inject
+ NetworkAsa1000vMapDao _networkAsa1000vMapDao;
+
+ protected boolean canHandle(Network network) {
+ if (network.getBroadcastDomainType() != BroadcastDomainType.Vlan) {
+ return false; //TODO: should handle VxLAN as well
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ super.configure(name, params);
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return true;
+ }
+
+ private static Map<Service, Map<Capability, String>> setCapabilities() {
+ Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+ capabilities.put(Service.Gateway, null);
+
+ Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
+ firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
+ firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress,egress");
+ firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
+ firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp");
+ firewallCapabilities.put(Capability.MultipleIps, "true");
+ capabilities.put(Service.Firewall, firewallCapabilities);
+
+ capabilities.put(Service.StaticNat, null);
+ capabilities.put(Service.PortForwarding, null);
+
+ Map<Capability, String> sourceNatCapabilities = new HashMap<Capability, String>();
+ sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
+ sourceNatCapabilities.put(Capability.RedundantRouter, "false"); //TODO:
+ capabilities.put(Service.SourceNat, sourceNatCapabilities);
+ return capabilities;
+ }
+
+ @Override
+ public Map<Service, Map<Capability, String>> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ public Provider getProvider() {
+ return Provider.CiscoVnmc;
+ }
+
+ private boolean createLogicalEdgeFirewall(long vlanId,
+ String gateway, String gatewayNetmask,
+ String publicIp, String publicNetmask,
+ List<String> publicGateways, long hostId) {
+ CreateLogicalEdgeFirewallCommand cmd = new CreateLogicalEdgeFirewallCommand(vlanId, publicIp, gateway, publicNetmask, gatewayNetmask);
+ for (String publicGateway : publicGateways) {
+ cmd.getPublicGateways().add(publicGateway);
+ }
+ Answer answer = _agentMgr.easySend(hostId, cmd);
+ return answer.getResult();
+ }
+
+ private boolean configureNexusVsmForAsa(long vlanId, String gateway,
+ String vsmUsername, String vsmPassword, String vsmIp,
+ String asaInPortProfile, long hostId) {
+ ConfigureNexusVsmForAsaCommand cmd = new ConfigureNexusVsmForAsaCommand(vlanId, gateway, vsmUsername, vsmPassword, vsmIp, asaInPortProfile);
+ Answer answer = _agentMgr.easySend(hostId, cmd);
+ return answer.getResult();
+ }
+
+ private boolean configureSourceNat(long vlanId, String guestCidr,
+ PublicIp sourceNatIp, long hostId) {
+ boolean add = (sourceNatIp.getState() == IpAddress.State.Releasing ? false : true);
+ IpAddressTO ip = new IpAddressTO(sourceNatIp.getAccountId(), sourceNatIp.getAddress().addr(), add, false,
+ sourceNatIp.isSourceNat(), sourceNatIp.getVlanTag(), sourceNatIp.getGateway(), sourceNatIp.getNetmask(), sourceNatIp.getMacAddress(),
+ null, sourceNatIp.isOneToOneNat());
+ boolean addSourceNat = false;
+ if (sourceNatIp.isSourceNat()) {
+ addSourceNat = add;
+ }
+
+ SetSourceNatCommand cmd = new SetSourceNatCommand(ip, addSourceNat);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, Long.toString(vlanId));
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, guestCidr);
+ Answer answer = _agentMgr.easySend(hostId, cmd);
+ return answer.getResult();
+ }
+
+ private boolean associateAsaWithLogicalEdgeFirewall(long vlanId,
+ String asaMgmtIp, long hostId) {
+ AssociateAsaWithLogicalEdgeFirewallCommand cmd =
+ new AssociateAsaWithLogicalEdgeFirewallCommand(vlanId, asaMgmtIp);
+ Answer answer = _agentMgr.easySend(hostId, cmd);
+ return answer.getResult();
+ }
+
+ @Override
+ public boolean implement(Network network, NetworkOffering offering,
+ DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+ DataCenter zone = _configMgr.getZone(network.getDataCenterId());
+
+ if (zone.getNetworkType() == NetworkType.Basic) {
+ s_logger.debug("Not handling network implement in zone of type " + NetworkType.Basic);
+ return false;
+ }
+
+ if (!canHandle(network)) {
+ return false;
+ }
+
+ List<CiscoVnmcControllerVO> devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No Cisco Vnmc device on network " + network.getName());
+ return false;
+ }
+
+ List<CiscoAsa1000vDeviceVO> asaList = _ciscoAsa1000vDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (asaList.isEmpty()) {
+ s_logger.debug("No Cisco ASA 1000v device on network " + network.getName());
+ return false;
+ }
+
+ NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (asaForNetwork != null) {
+ s_logger.debug("Cisco ASA 1000v device already associated with network " + network.getName());
+ return true;
+ }
+
+ if (!_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.CiscoVnmc)) {
+ s_logger.error("SourceNat service is not provided by Cisco Vnmc device on network " + network.getName());
+ return false;
+ }
+
+ Transaction txn = Transaction.currentTxn();
+ boolean status = false;
+ try {
+ txn.start();
+
+ // ensure that there is an ASA 1000v assigned to this network
+ CiscoAsa1000vDevice assignedAsa = assignAsa1000vToNetwork(network);
+ if (assignedAsa == null) {
+ s_logger.error("Unable to assign ASA 1000v device to network " + network.getName());
+ return false;
+ }
+
+ ClusterVO asaCluster = _clusterDao.findById(assignedAsa.getClusterId());
+ ClusterVSMMapVO clusterVsmMap = _clusterVsmMapDao.findByClusterId(assignedAsa.getClusterId());
+ if (clusterVsmMap == null) {
+ s_logger.error("Vmware cluster " + asaCluster.getName() + " has no Cisco Nexus VSM device associated with it");
+ return false;
+ }
+
+ CiscoNexusVSMDeviceVO vsmDevice = _vsmDeviceDao.findById(clusterVsmMap.getVsmId());
+ if (vsmDevice == null) {
+ s_logger.error("Unable to load details of Cisco Nexus VSM device associated with cluster " + asaCluster.getName());
+ return false;
+ }
+
+ CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
+ _hostDao.loadDetails(ciscoVnmcHost);
+ Account owner = context.getAccount();
+ PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, network);
+ String vlan = network.getBroadcastUri().getHost();
+ long vlanId = Long.parseLong(vlan);
+
+ List<VlanVO> vlanVOList = _vlanDao.listVlansByPhysicalNetworkId(network.getPhysicalNetworkId());
+ List<String> publicGateways = new ArrayList<String>();
+ for (VlanVO vlanVO : vlanVOList) {
+ publicGateways.add(vlanVO.getVlanGateway());
+ }
+
+ // create logical edge firewall in VNMC
+ String gatewayNetmask = NetUtils.getCidrNetmask(network.getCidr());
+ if (!createLogicalEdgeFirewall(vlanId, network.getGateway(), gatewayNetmask,
+ sourceNatIp.getAddress().addr(), sourceNatIp.getNetmask(), publicGateways, ciscoVnmcHost.getId())) {
+ s_logger.error("Failed to create logical edge firewall in Cisco VNMC device for network " + network.getName());
+ return false;
+ }
+
+ // create stuff in VSM for ASA device
+ if (!configureNexusVsmForAsa(vlanId, network.getGateway(),
+ vsmDevice.getUserName(), vsmDevice.getPassword(), vsmDevice.getipaddr(),
+ assignedAsa.getInPortProfile(), ciscoVnmcHost.getId())) {
+ s_logger.error("Failed to configure Cisco Nexus VSM " + vsmDevice.getipaddr() +
+ " for ASA device for network " + network.getName());
+ return false;
+ }
+
+ // configure source NAT
+ //if (!configureSourceNat(vlanId, network.getCidr(), sourceNatIp, ciscoVnmcHost.getId())) {
+ // s_logger.error("Failed to configure source NAT in Cisco VNMC device for network " + network.getName());
+ // return false;
+ //}
+
+ // associate Asa 1000v instance with logical edge firewall
+ if (!associateAsaWithLogicalEdgeFirewall(vlanId, assignedAsa.getManagementIp(), ciscoVnmcHost.getId())) {
+ s_logger.error("Failed to associate Cisco ASA 1000v (" + assignedAsa.getManagementIp() +
+ ") with logical edge firewall in VNMC for network " + network.getName());
+ return false;
+ }
+
+ status = true;
+ txn.commit();
+ } finally {
+ if (!status) {
+ txn.rollback();
+ //FIXME: also undo changes in VNMC, VSM if anything failed
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean prepare(Network network, NicProfile nic,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException,
+ InsufficientCapacityException {
+ if (vm.getType() != Type.User) {
+ return false;
+ }
+
+ // ensure that there is an ASA 1000v assigned to this network
+ NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (asaForNetwork == null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean release(Network network, NicProfile nic,
+ VirtualMachineProfile<? extends VirtualMachine> vm,
+ ReservationContext context) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+ return true;
+ }
+
+ private boolean cleanupLogicalEdgeFirewall(long vlanId, long hostId) {
+ CleanupLogicalEdgeFirewallCommand cmd = new CleanupLogicalEdgeFirewallCommand(vlanId);
+ Answer answer = _agentMgr.easySend(hostId, cmd);
+ return answer.getResult();
+ }
+
+ @Override
+ public boolean shutdown(Network network, ReservationContext context,
+ boolean cleanup) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+
+ unassignAsa1000vFromNetwork(network);
+
+ String vlan = network.getBroadcastUri().getHost();
+ long vlanId = Long.parseLong(vlan);
+ List<CiscoVnmcControllerVO> devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (!devices.isEmpty()) {
+ CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
+ cleanupLogicalEdgeFirewall(vlanId, ciscoVnmcHost.getId());
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isReady(PhysicalNetworkServiceProvider provider) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean shutdownProviderInstances(
+ PhysicalNetworkServiceProvider provider, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean canEnableIndividualServices() {
+ return true;
+ }
+
+ @Override
+ public boolean verifyServicesCombination(Set<Service> services) {
+ if (!services.contains(Service.Firewall)) {
+ s_logger.warn("CiscoVnmc must be used as Firewall Service Provider in the network");
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean destroy(Network network, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public List<Class<?>> getCommands() {
+ List<Class<?>> cmdList = new ArrayList<Class<?>>();
+ cmdList.add(AddCiscoVnmcResourceCmd.class);
+ cmdList.add(DeleteCiscoVnmcResourceCmd.class);
+ cmdList.add(ListCiscoVnmcResourcesCmd.class);
+ cmdList.add(AddCiscoAsa1000vResourceCmd.class);
+ cmdList.add(DeleteCiscoAsa1000vResourceCmd.class);
+ cmdList.add(ListCiscoAsa1000vResourcesCmd.class);
+ return cmdList;
+ }
+
+ @Override
+ public CiscoVnmcController addCiscoVnmcResource(AddCiscoVnmcResourceCmd cmd) {
+ String deviceName = Provider.CiscoVnmc.getName();
+ NetworkDevice networkDevice = NetworkDevice.getNetworkDevice(deviceName);
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ CiscoVnmcController ciscoVnmcResource = null;
+
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+ }
+ long zoneId = physicalNetwork.getDataCenterId();
+
+ PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(physicalNetwork.getId(), networkDevice.getNetworkServiceProvder());
+ if (ntwkSvcProvider == null) {
+ throw new CloudRuntimeException("Network Service Provider: " + networkDevice.getNetworkServiceProvder() +
+ " is not enabled in the physical network: " + physicalNetworkId + "to add this device");
+ } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+ throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() +
+ " is in shutdown state in the physical network: " + physicalNetworkId + "to add this device");
+ }
+
+ if (_ciscoVnmcDao.listByPhysicalNetwork(physicalNetworkId).size() != 0) {
+ throw new CloudRuntimeException("A Cisco Vnmc device is already configured on this physical network");
+ }
+
+ Map<String, String> params = new HashMap<String,String>();
+ params.put("guid", UUID.randomUUID().toString());
+ params.put("zoneId", String.valueOf(physicalNetwork.getDataCenterId()));
+ params.put("physicalNetworkId", String.valueOf(physicalNetwork.getId()));
+ params.put("name", "Cisco VNMC Controller - " + cmd.getHost());
+ params.put("ip", cmd.getHost());
+ params.put("username", cmd.getUsername());
+ params.put("password", cmd.getPassword());
+ params.put("transportzoneisotype", physicalNetwork.getIsolationMethods().get(0).toLowerCase()); // FIXME What to do with multiple isolation types
+
+ Map<String, Object> hostdetails = new HashMap<String,Object>();
+ hostdetails.putAll(params);
+
+ ServerResource resource = new CiscoVnmcResource();
+ Transaction txn = Transaction.currentTxn();
+ try {
+ resource.configure(cmd.getHost(), hostdetails);
+
+ Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.ExternalFirewall, params);
+ if (host != null) {
+ txn.start();
+
+ ciscoVnmcResource = new CiscoVnmcControllerVO(host.getId(), physicalNetworkId, ntwkSvcProvider.getProviderName(), deviceName);
+ _ciscoVnmcDao.persist((CiscoVnmcControllerVO)ciscoVnmcResource);
+
+ DetailVO detail = new DetailVO(host.getId(), "deviceid", String.valueOf(ciscoVnmcResource.getId()));
+ _hostDetailsDao.persist(detail);
+
+ txn.commit();
+ return ciscoVnmcResource;
+ } else {
+ throw new CloudRuntimeException("Failed to add Cisco Vnmc device due to internal error.");
+ }
+ } catch (ConfigurationException e) {
+ txn.rollback();
+ throw new CloudRuntimeException(e.getMessage());
+ }
+ }
+
+ @Override
+ public CiscoVnmcResourceResponse createCiscoVnmcResourceResponse(
+ CiscoVnmcController ciscoVnmcResourceVO) {
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcResourceVO.getHostId());
+
+ CiscoVnmcResourceResponse response = new CiscoVnmcResourceResponse();
+ response.setId(ciscoVnmcResourceVO.getUuid());
+ response.setPhysicalNetworkId(ciscoVnmcResourceVO.getPhysicalNetworkId());
+ response.setProviderName(ciscoVnmcResourceVO.getProviderName());
+ response.setResourceName(ciscoVnmcHost.getName());
+
+ return response;
+ }
+
+ @Override
+ public boolean deleteCiscoVnmcResource(DeleteCiscoVnmcResourceCmd cmd) {
+ Long vnmcResourceId = cmd.getCiscoVnmcResourceId();
+ CiscoVnmcControllerVO vnmcResource = _ciscoVnmcDao.findById(vnmcResourceId);
+ if (vnmcResource == null) {
+ throw new InvalidParameterValueException(
+ "Could not find a Cisco VNMC appliance with id " + vnmcResourceId);
+ }
+
+ // Check if there any ASA 1000v appliances
+ Long physicalNetworkId = vnmcResource.getPhysicalNetworkId();
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork != null) {
+ List<CiscoAsa1000vDeviceVO> responseList = _ciscoAsa1000vDao.listByPhysicalNetwork(physicalNetworkId);
+ if (responseList.size() > 0) {
+ throw new CloudRuntimeException(
+ "Cisco VNMC appliance with id " + vnmcResourceId +
+ " cannot be deleted as there Cisco ASA 1000v appliances using it");
+ }
+ }
+
+ HostVO vnmcHost = _hostDao.findById(vnmcResource.getHostId());
+ Long hostId = vnmcHost.getId();
+ vnmcHost.setResourceState(ResourceState.Maintenance);
+ _hostDao.update(hostId, vnmcHost);
+ _resourceMgr.deleteHost(hostId, false, false);
+ _ciscoVnmcDao.remove(vnmcResourceId);
+
+ return true;
+ }
+
+ @Override
+ public List<CiscoVnmcControllerVO> listCiscoVnmcResources(
+ ListCiscoVnmcResourcesCmd cmd) {
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ Long ciscoVnmcResourceId = cmd.getCiscoVnmcResourceId();
+ List<CiscoVnmcControllerVO> responseList = new ArrayList<CiscoVnmcControllerVO>();
+
+ if (physicalNetworkId == null && ciscoVnmcResourceId == null) {
+ throw new InvalidParameterValueException("Either physical network Id or vnmc device Id must be specified");
+ }
+
+ if (ciscoVnmcResourceId != null) {
+ CiscoVnmcControllerVO ciscoVnmcResource = _ciscoVnmcDao.findById(ciscoVnmcResourceId);
+ if (ciscoVnmcResource == null) {
+ throw new InvalidParameterValueException("Could not find Cisco Vnmc device with id: " + ciscoVnmcResource);
+ }
+ responseList.add(ciscoVnmcResource);
+ }
+ else {
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId);
+ }
+ responseList = _ciscoVnmcDao.listByPhysicalNetwork(physicalNetworkId);
+ }
+
+ return responseList;
+ }
+
+ @Override
+ public IpDeployer getIpDeployer(Network network) {
+ return this;
+ }
+
+ @Override
+ public boolean applyFWRules(Network network,
+ List<? extends FirewallRule> rules)
+ throws ResourceUnavailableException {
+
+ if (!_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, Provider.CiscoVnmc)) {
+ s_logger.error("Firewall service is not provided by Cisco Vnmc device on network " + network.getName());
+ return false;
+ }
+
+ // Find VNMC host for physical network
+ List<CiscoVnmcControllerVO> devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No Cisco Vnmc device on network " + network.getName());
+ return true;
+ }
+
+ // Find if ASA 1000v is associated with network
+ NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (asaForNetwork == null) {
+ s_logger.debug("Cisco ASA 1000v device is not associated with network " + network.getName());
+ return true;
+ }
+
+ if (network.getState() == Network.State.Allocated) {
+ s_logger.debug("External firewall was asked to apply firewall rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands.");
+ return true;
+ }
+
+ CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
+
+ List<FirewallRuleTO> rulesTO = new ArrayList<FirewallRuleTO>();
+ for (FirewallRule rule : rules) {
+ IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+ FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getPurpose(), rule.getTrafficType());
+ rulesTO.add(ruleTO);
+ }
+
+ if (!rulesTO.isEmpty()) {
+ SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, network.getBroadcastUri().getHost());
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
+ Answer answer = _agentMgr.easySend(ciscoVnmcHost.getId(), cmd);
+ if (answer == null || !answer.getResult()) {
+ String details = (answer != null) ? answer.getDetails() : "details unavailable";
+ String msg = "Unable to apply firewall rules to Cisco ASA 1000v appliance due to: " + details + ".";
+ s_logger.error(msg);
+ throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean applyPFRules(Network network, List<PortForwardingRule> rules)
+ throws ResourceUnavailableException {
+
+ if (!_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.PortForwarding, Provider.CiscoVnmc)) {
+ s_logger.error("Port forwarding service is not provided by Cisco Vnmc device on network " + network.getName());
+ return false;
+ }
+
+ // Find VNMC host for physical network
+ List<CiscoVnmcControllerVO> devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No Cisco Vnmc device on network " + network.getName());
+ return true;
+ }
+
+ // Find if ASA 1000v is associated with network
+ NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (asaForNetwork == null) {
+ s_logger.debug("Cisco ASA 1000v device is not associated with network " + network.getName());
+ return true;
+ }
+
+ if (network.getState() == Network.State.Allocated) {
+ s_logger.debug("External firewall was asked to apply port forwarding rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands.");
+ return true;
+ }
+
+ CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
+
+ List<PortForwardingRuleTO> rulesTO = new ArrayList<PortForwardingRuleTO>();
+ for (PortForwardingRule rule : rules) {
+ IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+ Vlan vlan = _vlanDao.findById(sourceIp.getVlanId());
+ PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, vlan.getVlanTag(), sourceIp.getAddress().addr());
+ rulesTO.add(ruleTO);
+ }
+
+ if (!rulesTO.isEmpty()) {
+ SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rulesTO);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, network.getBroadcastUri().getHost());
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
+ Answer answer = _agentMgr.easySend(ciscoVnmcHost.getId(), cmd);
+ if (answer == null || !answer.getResult()) {
+ String details = (answer != null) ? answer.getDetails() : "details unavailable";
+ String msg = "Unable to apply port forwarding rules to Cisco ASA 1000v appliance due to: " + details + ".";
+ s_logger.error(msg);
+ throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean applyStaticNats(Network network,
+ List<? extends StaticNat> rules)
+ throws ResourceUnavailableException {
+ if (!_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.StaticNat, Provider.CiscoVnmc)) {
+ s_logger.error("Static NAT service is not provided by Cisco Vnmc device on network " + network.getName());
+ return false;
+ }
+
+ // Find VNMC host for physical network
+ List<CiscoVnmcControllerVO> devices = _ciscoVnmcDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ if (devices.isEmpty()) {
+ s_logger.error("No Cisco Vnmc device on network " + network.getName());
+ return true;
+ }
+
+ // Find if ASA 1000v is associated with network
+ NetworkAsa1000vMapVO asaForNetwork = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (asaForNetwork == null) {
+ s_logger.debug("Cisco ASA 1000v device is not associated with network " + network.getName());
+ return true;
+ }
+
+ if (network.getState() == Network.State.Allocated) {
+ s_logger.debug("External firewall was asked to apply static NAT rules for network with ID " + network.getId() + "; this network is not implemented. Skipping backend commands.");
+ return true;
+ }
+
+ CiscoVnmcControllerVO ciscoVnmcDevice = devices.get(0);
+ HostVO ciscoVnmcHost = _hostDao.findById(ciscoVnmcDevice.getHostId());
+
+ List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>();
+ for (StaticNat rule : rules) {
+ IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+ StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null,
+ null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false);
+ rulesTO.add(ruleTO);
+ }
+
+ if (!rulesTO.isEmpty()) {
+ SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null);
+ cmd.setContextParam(NetworkElementCommand.GUEST_VLAN_TAG, network.getBroadcastUri().getHost());
+ cmd.setContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr());
+ Answer answer = _agentMgr.easySend(ciscoVnmcHost.getId(), cmd);
+ if (answer == null || !answer.getResult()) {
+ String details = (answer != null) ? answer.getDetails() : "details unavailable";
+ String msg = "Unable to apply static NAT rules to Cisco ASA 1000v appliance due to: " + details + ".";
+ s_logger.error(msg);
+ throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId());
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean applyIps(Network network,
+ List<? extends PublicIpAddress> ipAddress, Set<Service> services)
+ throws ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public HostVO createHostVOForConnectedAgent(HostVO host,
+ StartupCommand[] cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host,
+ StartupCommand[] startup, ServerResource resource,
+ Map<String, String> details, List<String> hostTags) {
+ if (!(startup[0] instanceof StartupExternalFirewallCommand)) {
+ return null;
+ }
+ host.setType(Host.Type.ExternalFirewall);
+ return host;
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+ boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ if (host.getType() != com.cloud.host.Host.Type.ExternalFirewall) {
+ return null;
+ }
+ return new DeleteHostAnswer(true);
+ }
+
+ @Override
+ public CiscoAsa1000vDevice addCiscoAsa1000vResource(
+ AddCiscoAsa1000vResourceCmd cmd) {
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ CiscoAsa1000vDevice ciscoAsa1000vResource = null;
+
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find phyical network with ID: " + physicalNetworkId);
+ }
+
+ ciscoAsa1000vResource = new CiscoAsa1000vDeviceVO(physicalNetworkId, cmd.getManagementIp(), cmd.getInPortProfile(), cmd.getClusterId());
+ _ciscoAsa1000vDao.persist((CiscoAsa1000vDeviceVO)ciscoAsa1000vResource);
+
+ return ciscoAsa1000vResource;
+ }
+
+ @Override
+ public CiscoAsa1000vResourceResponse createCiscoAsa1000vResourceResponse(
+ CiscoAsa1000vDevice ciscoAsa1000vDeviceVO) {
+ CiscoAsa1000vResourceResponse response = new CiscoAsa1000vResourceResponse();
+ response.setId(ciscoAsa1000vDeviceVO.getUuid());
+ response.setManagementIp(ciscoAsa1000vDeviceVO.getManagementIp());
+ response.setInPortProfile(ciscoAsa1000vDeviceVO.getInPortProfile());
+
+ NetworkAsa1000vMapVO networkAsaMap = _networkAsa1000vMapDao.findByAsa1000vId(ciscoAsa1000vDeviceVO.getId());
+ if (networkAsaMap != null) {
+ response.setGuestNetworkId(networkAsaMap.getNetworkId());
+ }
+
+ return response;
+ }
+
+ @Override
+ public boolean deleteCiscoAsa1000vResource(
+ DeleteCiscoAsa1000vResourceCmd cmd) {
+ Long asaResourceId = cmd.getCiscoAsa1000vResourceId();
+ CiscoAsa1000vDeviceVO asaResource = _ciscoAsa1000vDao.findById(asaResourceId);
+ if (asaResource == null) {
+ throw new InvalidParameterValueException(
+ "Could not find a Cisco ASA 1000v appliance with id " + asaResourceId);
+ }
+
+ NetworkAsa1000vMapVO networkAsaMap = _networkAsa1000vMapDao.findByAsa1000vId(asaResource.getId());
+ if (networkAsaMap != null) {
+ throw new CloudRuntimeException(
+ "Cisco ASA 1000v appliance with id " + asaResourceId +
+ " cannot be deleted as it is associated with guest network");
+ }
+
+ _ciscoAsa1000vDao.remove(asaResourceId);
+
+ return true;
+ }
+
+ @Override
+ public List<CiscoAsa1000vDeviceVO> listCiscoAsa1000vResources(
+ ListCiscoAsa1000vResourcesCmd cmd) {
+ Long physicalNetworkId = cmd.getPhysicalNetworkId();
+ Long ciscoAsa1000vResourceId = cmd.getCiscoAsa1000vResourceId();
+ List<CiscoAsa1000vDeviceVO> responseList = new ArrayList<CiscoAsa1000vDeviceVO>();
+
+ if (physicalNetworkId == null && ciscoAsa1000vResourceId == null) {
+ throw new InvalidParameterValueException("Either physical network Id or Asa 1000v device Id must be specified");
+ }
+
+ if (ciscoAsa1000vResourceId != null) {
+ CiscoAsa1000vDeviceVO ciscoAsa1000vResource = _ciscoAsa1000vDao.findById(ciscoAsa1000vResourceId);
+ if (ciscoAsa1000vResource == null) {
+ throw new InvalidParameterValueException("Could not find Cisco Asa 1000v device with id: " + ciscoAsa1000vResourceId);
+ }
+ responseList.add(ciscoAsa1000vResource);
+ } else {
+ PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+ if (physicalNetwork == null) {
+ throw new InvalidParameterValueException("Could not find a physical network with id: " + physicalNetworkId);
+ }
+ responseList = _ciscoAsa1000vDao.listByPhysicalNetwork(physicalNetworkId);
+ }
+
+ return responseList;
+ }
+
+ @Override
+ public CiscoAsa1000vDevice assignAsa1000vToNetwork(Network network) {
+ List<CiscoAsa1000vDeviceVO> asaList = _ciscoAsa1000vDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+ for (CiscoAsa1000vDeviceVO asa : asaList) {
+ NetworkAsa1000vMapVO assignedToNetwork = _networkAsa1000vMapDao.findByAsa1000vId(asa.getId());
+ if (assignedToNetwork == null) {
+ NetworkAsa1000vMapVO networkAsaMap = new NetworkAsa1000vMapVO(network.getId(), asa.getId());
+ _networkAsa1000vMapDao.persist(networkAsaMap);
+ return asa;
+ }
+ }
+ return null;
+ }
+
+ private void unassignAsa1000vFromNetwork(Network network) {
+ NetworkAsa1000vMapVO networkAsaMap = _networkAsa1000vMapDao.findByNetworkId(network.getId());
+ if (networkAsaMap != null) {
+ _networkAsa1000vMapDao.remove(networkAsaMap.getId());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e94c7025/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java
new file mode 100644
index 0000000..e8eb473
--- /dev/null
+++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElementService.java
@@ -0,0 +1,42 @@
+// 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.element;
+
+import java.util.List;
+
+import com.cloud.api.commands.AddCiscoVnmcResourceCmd;
+import com.cloud.api.commands.DeleteCiscoVnmcResourceCmd;
+import com.cloud.api.commands.ListCiscoVnmcResourcesCmd;
+import com.cloud.api.response.CiscoVnmcResourceResponse;
+import com.cloud.network.cisco.CiscoVnmcController;
+import com.cloud.network.cisco.CiscoVnmcControllerVO;
+import com.cloud.utils.component.PluggableService;
+
+public interface CiscoVnmcElementService extends PluggableService {
+
+ //public static final Provider CiscoVnmc = new Provider("CiscoVnmc", true);
+
+ public CiscoVnmcController addCiscoVnmcResource(AddCiscoVnmcResourceCmd cmd);
+
+ public CiscoVnmcResourceResponse createCiscoVnmcResourceResponse(
+ CiscoVnmcController CiscoVnmcResourceVO);
+
+ boolean deleteCiscoVnmcResource(DeleteCiscoVnmcResourceCmd cmd);
+
+ List<CiscoVnmcControllerVO> listCiscoVnmcResources(ListCiscoVnmcResourcesCmd cmd);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e94c7025/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java
new file mode 100644
index 0000000..9155978
--- /dev/null
+++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java
@@ -0,0 +1,780 @@
+// 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AssociateAsaWithLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.CleanupLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ConfigureNexusVsmForAsaCommand;
+import com.cloud.agent.api.CreateLogicalEdgeFirewallCommand;
+import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer;
+import com.cloud.agent.api.ExternalNetworkResourceUsageCommand;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalFirewallCommand;
+import com.cloud.agent.api.routing.IpAssocAnswer;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+import com.cloud.agent.api.to.StaticNatRuleTO;
+import com.cloud.host.Host;
+import com.cloud.network.cisco.CiscoVnmcConnectionImpl;
+import com.cloud.network.rules.FirewallRule.TrafficType;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.OperationType;
+import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.SwitchPortMode;
+import com.cloud.utils.exception.ExecutionException;
+import com.cloud.utils.net.NetUtils;
+
+public class CiscoVnmcResource implements ServerResource {
+
+ private String _name;
+ private String _zoneId;
+ private String _physicalNetworkId;
+ private String _ip;
+ private String _username;
+ private String _password;
+ private String _guid;
+ private Integer _numRetries;
+
+ private CiscoVnmcConnectionImpl _connection;
+
+ public void setConnection(CiscoVnmcConnectionImpl connection) {
+ this._connection = connection;
+ }
+
+ private final Logger s_logger = Logger.getLogger(CiscoVnmcResource.class);
+
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof ReadyCommand) {
+ return execute((ReadyCommand) cmd);
+ } else if (cmd instanceof MaintainCommand) {
+ return execute((MaintainCommand) cmd);
+ } else if (cmd instanceof IpAssocCommand) {
+ return execute((IpAssocCommand) cmd);
+ } else if (cmd instanceof SetSourceNatCommand) {
+ return execute((SetSourceNatCommand) cmd);
+ } else if (cmd instanceof SetFirewallRulesCommand) {
+ return execute((SetFirewallRulesCommand) cmd);
+ } else if (cmd instanceof SetStaticNatRulesCommand) {
+ return execute((SetStaticNatRulesCommand) cmd);
+ } else if (cmd instanceof SetPortForwardingRulesCommand) {
+ return execute((SetPortForwardingRulesCommand) cmd);
+ } else if (cmd instanceof ExternalNetworkResourceUsageCommand) {
+ return execute((ExternalNetworkResourceUsageCommand) cmd);
+ } else if (cmd instanceof CreateLogicalEdgeFirewallCommand) {
+ return execute((CreateLogicalEdgeFirewallCommand)cmd);
+ } else if (cmd instanceof CleanupLogicalEdgeFirewallCommand) {
+ return execute((CleanupLogicalEdgeFirewallCommand)cmd);
+ } else if (cmd instanceof ConfigureNexusVsmForAsaCommand) {
+ return execute((ConfigureNexusVsmForAsaCommand)cmd);
+ } else if (cmd instanceof AssociateAsaWithLogicalEdgeFirewallCommand) {
+ return execute((AssociateAsaWithLogicalEdgeFirewallCommand)cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ try {
+ _name = (String) params.get("name");
+ if (_name == null) {
+ throw new ConfigurationException("Unable to find name");
+ }
+
+ _zoneId = (String) params.get("zoneId");
+ if (_zoneId == null) {
+ throw new ConfigurationException("Unable to find zone");
+ }
+
+ _physicalNetworkId = (String) params.get("physicalNetworkId");
+ if (_physicalNetworkId == null) {
+ throw new ConfigurationException("Unable to find physical network id in the configuration parameters");
+ }
+
+ _ip = (String) params.get("ip");
+ if (_ip == null) {
+ throw new ConfigurationException("Unable to find IP");
+ }
+
+ _username = (String) params.get("username");
+ if (_username == null) {
+ throw new ConfigurationException("Unable to find username");
+ }
+
+ _password = (String) params.get("password");
+ if (_password == null) {
+ throw new ConfigurationException("Unable to find password");
+ }
+
+ _guid = (String)params.get("guid");
+ if (_guid == null) {
+ throw new ConfigurationException("Unable to find the guid");
+ }
+
+ _numRetries = NumbersUtil.parseInt((String) params.get("numretries"), 1);
+
+ NumbersUtil.parseInt((String) params.get("timeout"), 300);
+
+ // Open a socket and login
+ _connection = new CiscoVnmcConnectionImpl(_ip, _username, _password);
+ //if (!refreshVnmcConnection()) {
+ // throw new ConfigurationException("Unable to open a connection to the VNMC.");
+ //}
+
+ return true;
+ } catch (Exception e) {
+ throw new ConfigurationException(e.getMessage());
+ }
+
+ }
+
+ public StartupCommand[] initialize() {
+ StartupExternalFirewallCommand cmd = new StartupExternalFirewallCommand();
+ cmd.setName(_name);
+ cmd.setDataCenter(_zoneId);
+ cmd.setPod("");
+ cmd.setPrivateIpAddress(_ip);
+ cmd.setStorageIpAddress("");
+ cmd.setVersion("");
+ cmd.setGuid(_guid);
+ return new StartupCommand[] { cmd };
+ }
+
+ public Host.Type getType() {
+ return Host.Type.ExternalFirewall;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(final long id) {
+ if (!refreshVnmcConnection()) {
+ return null;
+ }
+ return new PingCommand(Host.Type.ExternalFirewall, id);
+ }
+
+ @Override
+ public void disconnected() {
+ }
+
+ public IAgentControl getAgentControl() {
+ return null;
+ }
+
+ public void setAgentControl(IAgentControl agentControl) {
+ return;
+ }
+
+ private Answer execute(ReadyCommand cmd) {
+ return new ReadyAnswer(cmd);
+ }
+
+ private Answer execute(MaintainCommand cmd) {
+ return new MaintainAnswer(cmd);
+ }
+
+ private ExternalNetworkResourceUsageAnswer execute(ExternalNetworkResourceUsageCommand cmd) {
+ return new ExternalNetworkResourceUsageAnswer(cmd);
+ }
+
+ /*
+ * Login
+ */
+ private boolean refreshVnmcConnection() {
+ boolean ret = false;
+ try {
+ ret = _connection.login();
+ } catch (ExecutionException ex) {
+ s_logger.error("Login to Vnmc failed", ex);
+ }
+ return ret;
+ }
+
+ private synchronized Answer execute(IpAssocCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(IpAssocCommand cmd, int numRetries) {
+ String[] results = new String[cmd.getIpAddresses().length];
+ return new IpAssocAnswer(cmd, results);
+ }
+
+ private String[] getIpRangeFromCidr(String cidr) {
+ String[] result = new String[2];
+ String[] cidrData = cidr.split("\\/");
+ assert (cidrData.length == 2) : "Something is wrong with source cidr " + cidr;
+ long size = Long.valueOf(cidrData[1]);
+ result[0] = cidrData[0];
+ result[1] = cidrData[0];
+ if (size < 32) {
+ result[0] = NetUtils.getIpRangeStartIpFromCidr(cidrData[0], size);
+ result[1] = NetUtils.getIpRangeEndIpFromCidr(cidrData[0], size);
+ }
+ return result;
+ }
+
+ /*
+ * Source NAT
+ */
+ private synchronized Answer execute(SetSourceNatCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(SetSourceNatCommand cmd, int numRetries) {
+ String vlanId = cmd.getContextParam(NetworkElementCommand.GUEST_VLAN_TAG);
+ String tenant = "vlan-" + vlanId;
+ String policyIdentifier = cmd.getIpAddress().getPublicIp().replace('.', '-');
+ try {
+ if (!_connection.createTenantVDCNatPolicySet(tenant)) {
+ throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCSourceNatPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create source NAT policy in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCSourceNatPolicyRef(tenant, policyIdentifier)) {
+ throw new Exception("Failed to associate source NAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCSourceNatIpPool(tenant, policyIdentifier, cmd.getIpAddress().getPublicIp())) {
+ throw new Exception("Failed to create source NAT ip pool in VNMC for guest network with vlan " + vlanId);
+ }
+
+ String[] ipRange = getIpRangeFromCidr(cmd.getContextParam(NetworkElementCommand.GUEST_NETWORK_CIDR));
+ if (!_connection.createTenantVDCSourceNatRule(tenant, policyIdentifier, ipRange[0], ipRange[1])) {
+ throw new Exception("Failed to create source NAT rule in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.associateNatPolicySet(tenant)) {
+ throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
+ }
+ } catch (Throwable e) {
+ String msg = "SetSourceNatCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Firewall rule
+ */
+ private synchronized Answer execute(SetFirewallRulesCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(SetFirewallRulesCommand cmd, int numRetries) {
+ String vlanId = cmd.getContextParam(NetworkElementCommand.GUEST_VLAN_TAG);
+ String tenant = "vlan-" + vlanId;
+
+ FirewallRuleTO[] rules = cmd.getRules();
+ Map<String, List<FirewallRuleTO>> publicIpRulesMap = new HashMap<String, List<FirewallRuleTO>>();
+ for (FirewallRuleTO rule : rules) {
+ String publicIp = rule.getSrcIp();
+ if (!publicIpRulesMap.containsKey(publicIp)) {
+ List<FirewallRuleTO> publicIpRulesList = new ArrayList<FirewallRuleTO>();
+ publicIpRulesMap.put(publicIp, publicIpRulesList);
+ }
+ publicIpRulesMap.get(publicIp).add(rule);
+ }
+
+ try {
+ if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
+ throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
+ throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (String publicIp : publicIpRulesMap.keySet()) {
+ String policyIdentifier = publicIp.replace('.', '-');
+
+ if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
+ throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
+ throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (FirewallRuleTO rule : publicIpRulesMap.get(publicIp)) {
+ if (rule.revoked()) {
+ if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
+ throw new Exception("Failed to delete ACL rule in VNMC for guest network with vlan " + vlanId);
+ }
+ } else {
+ String[] externalIpRange = getIpRangeFromCidr(rule.getSourceCidrList().get(0));
+ if (rule.getTrafficType() == TrafficType.Ingress) {
+ if (!rule.getProtocol().equalsIgnoreCase("icmp")) {
+ if (!_connection.createTenantVDCIngressAclRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1],
+ Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]), publicIp)) {
+ throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
+ }
+ } else {
+ if (!_connection.createTenantVDCIngressAclRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(), externalIpRange[0], externalIpRange[1], publicIp)) {
+ throw new Exception("Failed to create ACL ingress rule in VNMC for guest network with vlan " + vlanId);
+ }
+ }
+ } else {
+ if (!rule.getProtocol().equalsIgnoreCase("icmp")) {
+ if (!_connection.createTenantVDCEgressAclRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(),
+ Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]), publicIp,
+ externalIpRange[0], externalIpRange[1])) {
+ throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
+ }
+ } else {
+ if (!_connection.createTenantVDCEgressAclRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(), publicIp, externalIpRange[0], externalIpRange[1])) {
+ throw new Exception("Failed to create ACL egress rule in VNMC for guest network with vlan " + vlanId);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!_connection.associateAclPolicySet(tenant)) {
+ throw new Exception("Failed to associate ACL policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
+ }
+ } catch (Throwable e) {
+ String msg = "SetFirewallRulesCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Static NAT
+ */
+ private synchronized Answer execute(SetStaticNatRulesCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(SetStaticNatRulesCommand cmd, int numRetries) {
+ String vlanId = cmd.getContextParam(NetworkElementCommand.GUEST_VLAN_TAG);
+ String tenant = "vlan-" + vlanId;
+
+ StaticNatRuleTO[] rules = cmd.getRules();
+ Map<String, List<StaticNatRuleTO>> publicIpRulesMap = new HashMap<String, List<StaticNatRuleTO>>();
+ for (StaticNatRuleTO rule : rules) {
+ String publicIp = rule.getSrcIp();
+ if (!publicIpRulesMap.containsKey(publicIp)) {
+ List<StaticNatRuleTO> publicIpRulesList = new ArrayList<StaticNatRuleTO>();
+ publicIpRulesMap.put(publicIp, publicIpRulesList);
+ }
+ publicIpRulesMap.get(publicIp).add(rule);
+ }
+
+ try {
+ if (!_connection.createTenantVDCNatPolicySet(tenant)) {
+ throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
+ throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
+ throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (String publicIp : publicIpRulesMap.keySet()) {
+ String policyIdentifier = publicIp.replace('.', '-');
+
+ if (!_connection.createTenantVDCDNatPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create DNAT policy in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCDNatPolicyRef(tenant, policyIdentifier)) {
+ throw new Exception("Failed to associate DNAT policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
+ throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
+ throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (StaticNatRuleTO rule : publicIpRulesMap.get(publicIp)) {
+ if (rule.revoked()) {
+ if (!_connection.deleteTenantVDCDNatRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
+ throw new Exception("Failed to delete DNAT rule in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
+ throw new Exception("Failed to delete ACL ingress rule for DNAT in VNMC for guest network with vlan " + vlanId);
+ }
+ } else {
+ if (!_connection.createTenantVDCDNatIpPool(tenant, policyIdentifier + "-" + rule.getId(), rule.getDstIp())) {
+ throw new Exception("Failed to create DNAT ip pool in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCDNatRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier, rule.getSrcIp())) {
+ throw new Exception("Failed to create DNAT rule in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclRuleForDNat(tenant,
+ Long.toString(rule.getId()), policyIdentifier, rule.getDstIp())) {
+ throw new Exception("Failed to create ACL rule for DNAT in VNMC for guest network with vlan " + vlanId);
+ }
+ }
+ }
+ }
+
+ if (!_connection.associateAclPolicySet(tenant)) {
+ throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
+ }
+ } catch (Throwable e) {
+ String msg = "SetSourceNatCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Destination NAT
+ */
+ private synchronized Answer execute(SetPortForwardingRulesCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(SetPortForwardingRulesCommand cmd, int numRetries) {
+ String vlanId = cmd.getContextParam(NetworkElementCommand.GUEST_VLAN_TAG);
+ String tenant = "vlan-" + vlanId;
+
+ PortForwardingRuleTO[] rules = cmd.getRules();
+ Map<String, List<PortForwardingRuleTO>> publicIpRulesMap = new HashMap<String, List<PortForwardingRuleTO>>();
+ for (PortForwardingRuleTO rule : rules) {
+ String publicIp = rule.getSrcIp();
+ if (!publicIpRulesMap.containsKey(publicIp)) {
+ List<PortForwardingRuleTO> publicIpRulesList = new ArrayList<PortForwardingRuleTO>();
+ publicIpRulesMap.put(publicIp, publicIpRulesList);
+ }
+ publicIpRulesMap.get(publicIp).add(rule);
+ }
+
+ try {
+ if (!_connection.createTenantVDCNatPolicySet(tenant)) {
+ throw new Exception("Failed to create NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicySet(tenant, true)) {
+ throw new Exception("Failed to create ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicySet(tenant, false)) {
+ throw new Exception("Failed to create ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (String publicIp : publicIpRulesMap.keySet()) {
+ String policyIdentifier = publicIp.replace('.', '-');
+
+ if (!_connection.createTenantVDCPFPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create PF policy in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCPFPolicyRef(tenant, policyIdentifier)) {
+ throw new Exception("Failed to associate PF policy with NAT policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclPolicy(tenant, policyIdentifier)) {
+ throw new Exception("Failed to create ACL policy in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, true)) {
+ throw new Exception("Failed to associate ACL policy with ACL ingress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCAclPolicyRef(tenant, policyIdentifier, false)) {
+ throw new Exception("Failed to associate ACL policy with ACL egress policy set in VNMC for guest network with vlan " + vlanId);
+ }
+
+ for (PortForwardingRuleTO rule : publicIpRulesMap.get(publicIp)) {
+ if (rule.revoked()) {
+ if (!_connection.deleteTenantVDCPFRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
+ throw new Exception("Failed to delete PF rule in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.deleteTenantVDCAclRule(tenant, Long.toString(rule.getId()), policyIdentifier)) {
+ throw new Exception("Failed to delete ACL ingress rule for PF in VNMC for guest network with vlan " + vlanId);
+ }
+ } else {
+ if (!_connection.createTenantVDCPFIpPool(tenant, policyIdentifier + "-" + rule.getId(), rule.getDstIp())) {
+ throw new Exception("Failed to create PF ip pool in VNMC for guest network with vlan " + vlanId);
+ }
+ if (!_connection.createTenantVDCPFPortPool(tenant, policyIdentifier + "-" + rule.getId(),
+ Integer.toString(rule.getDstPortRange()[0]), Integer.toString(rule.getDstPortRange()[1]))) {
+ throw new Exception("Failed to create PF port pool in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCPFRule(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(), rule.getSrcIp(),
+ Integer.toString(rule.getSrcPortRange()[0]), Integer.toString(rule.getSrcPortRange()[1]))) {
+ throw new Exception("Failed to create PF rule in VNMC for guest network with vlan " + vlanId);
+ }
+
+ if (!_connection.createTenantVDCAclRuleForPF(tenant,
+ Long.toString(rule.getId()), policyIdentifier,
+ rule.getProtocol().toUpperCase(), rule.getDstIp(),
+ Integer.toString(rule.getDstPortRange()[0]), Integer.toString(rule.getDstPortRange()[1]))) {
+ throw new Exception("Failed to create ACL rule for PF in VNMC for guest network with vlan " + vlanId);
+ }
+ }
+ }
+ }
+
+ if (!_connection.associateAclPolicySet(tenant)) {
+ throw new Exception("Failed to associate source NAT policy set with edge security profile in VNMC for guest network with vlan " + vlanId);
+ }
+ } catch (Throwable e) {
+ String msg = "SetSourceNatCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Logical edge firewall
+ */
+ private synchronized Answer execute(CreateLogicalEdgeFirewallCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private void createEdgeDeviceProfile(String tenant, List<String> gateways, Long vlanId) throws Exception {
+ // create edge device profile
+ if (!_connection.createTenantVDCEdgeDeviceProfile(tenant))
+ throw new Exception("Failed to create tenant edge device profile in VNMC for guest network with vlan " + vlanId);
+
+ // create edge static route policy
+ if (!_connection.createTenantVDCEdgeStaticRoutePolicy(tenant))
+ throw new Exception("Failed to create tenant edge static route policy in VNMC for guest network with vlan " + vlanId);
+
+ // create edge static route for all gateways
+ for (String gateway : gateways) {
+ if (!_connection.createTenantVDCEdgeStaticRoute(tenant, gateway, "0.0.0.0", "0.0.0.0"))
+ throw new Exception("Failed to create tenant edge static route in VNMC for guest network with vlan " + vlanId);
+ }
+
+ // associate edge
+ if (!_connection.associateTenantVDCEdgeStaticRoutePolicy(tenant))
+ throw new Exception("Failed to associate edge static route policy with edge device profile in VNMC for guest network with vlan " + vlanId);
+ }
+
+ private Answer execute(CreateLogicalEdgeFirewallCommand cmd, int numRetries) {
+ String tenant = "vlan-" + cmd.getVlanId();
+ try {
+ // create tenant
+ if (!_connection.createTenant(tenant))
+ throw new Exception("Failed to create tenant in VNMC for guest network with vlan " + cmd.getVlanId());
+
+ // create tenant VDC
+ if (!_connection.createTenantVDC(tenant))
+ throw new Exception("Failed to create tenant VDC in VNMC for guest network with vlan " + cmd.getVlanId());
+
+ // create edge security profile
+ if (!_connection.createTenantVDCEdgeSecurityProfile(tenant))
+ throw new Exception("Failed to create tenant edge security profile in VNMC for guest network with vlan " + cmd.getVlanId());
+
+ // create edge device profile and associated route
+ createEdgeDeviceProfile(tenant, cmd.getPublicGateways(), cmd.getVlanId());
+
+ // create logical edge firewall
+ if (!_connection.createEdgeFirewall(tenant, cmd.getPublicIp(), cmd.getInternalIp(), cmd.getPublicSubnet(), cmd.getInternalSubnet()))
+ throw new Exception("Failed to create edge firewall in VNMC for guest network with vlan " + cmd.getVlanId());
+ } catch (Throwable e) {
+ String msg = "CreateLogicalEdgeFirewallCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Create vservice node and update inside port profile for ASA appliance in VSM
+ */
+ private synchronized Answer execute(ConfigureNexusVsmForAsaCommand cmd) {
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(ConfigureNexusVsmForAsaCommand cmd, int numRetries) {
+ String vlanId = Long.toString(cmd.getVlanId());
+ NetconfHelper helper = null;
+ List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
+ params.add(new Pair<OperationType, String>(OperationType.addvlanid, vlanId));
+ try {
+ helper = new NetconfHelper(cmd.getVsmIp(), cmd.getVsmUsername(), cmd.getVsmPassword());
+ s_logger.debug("Connected to Cisco VSM " + cmd.getVsmIp());
+ helper.addVServiceNode(vlanId, cmd.getIpAddress());
+ s_logger.debug("Created vservice node for ASA appliance in Cisco VSM for vlan " + vlanId);
+ helper.updatePortProfile(cmd.getAsaInPortProfile(), SwitchPortMode.access, params);
+ s_logger.debug("Updated inside port profile for ASA appliance in Cisco VSM with new vlan " + vlanId);
+ } catch (Throwable e) {
+ String msg = "ConfigureVSMForASACommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ } finally {
+ helper.disconnect();
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Associates ASA 1000v with logical edge firewall in VNMC
+ */
+ private synchronized Answer execute(AssociateAsaWithLogicalEdgeFirewallCommand cmd) {
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(AssociateAsaWithLogicalEdgeFirewallCommand cmd, int numRetries) {
+ String tenant = "vlan-" + cmd.getVlanId();
+ try {
+ Map<String, String> availableAsaAppliances = _connection.listUnAssocAsa1000v();
+ if (availableAsaAppliances.isEmpty()) {
+ throw new Exception("No ASA 1000v available to associate with logical edge firewall for guest vlan " + cmd.getVlanId());
+ }
+
+ String asaInstanceDn = availableAsaAppliances.get(cmd.getAsaMgmtIp());
+ if (asaInstanceDn == null) {
+ throw new Exception("Requested ASA 1000v (" + cmd.getAsaMgmtIp() + ") is not available");
+ }
+
+ if (!_connection.assignAsa1000v(tenant, asaInstanceDn)) {
+ throw new Exception("Failed to associate ASA 1000v (" + cmd.getAsaMgmtIp() + ") with logical edge firewall for guest vlan " + cmd.getVlanId());
+ }
+ } catch (Throwable e) {
+ String msg = "AssociateAsaWithLogicalEdgeFirewallCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ /*
+ * Cleanup
+ */
+ private synchronized Answer execute(CleanupLogicalEdgeFirewallCommand cmd) {
+ refreshVnmcConnection();
+ return execute(cmd, _numRetries);
+ }
+
+ private Answer execute(CleanupLogicalEdgeFirewallCommand cmd, int numRetries) {
+ String tenant = "vlan-" + cmd.getVlanId();
+ try {
+ _connection.deleteTenant(tenant);
+ } catch (Throwable e) {
+ String msg = "CleanupLogicalEdgeFirewallCommand failed due to " + e.getMessage();
+ s_logger.error(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ return new Answer(cmd, true, "Success");
+ }
+
+ @Override
+ public void setName(String name) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void setConfigParams(Map<String, Object> params) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public Map<String, Object> getConfigParams() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getRunLevel() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void setRunLevel(int level) {
+ // TODO Auto-generated method stub
+ }
+
+}