From 781f0b4966a039f434d954ef125661b6071bbcd3 Mon Sep 17 00:00:00 2001 From: Vijayendra Bhamidipati Date: Tue, 8 May 2012 20:48:01 -0700 Subject: [PATCH] Bug CS-9919: Support for Nexus Swiches (Cisco Vswitches) Description: 1. Added the PortProfile infrastructure: a. PortProfileVO : The VO class to represent a db record of the table port_profile. Each db record represents one port profile. b. PortProfileDao: The interface that declares search functions on the port_profile table. c. PortProfileDaoImpl: The class that defines the interfaces declared in PortProfileDao. d. PortProfileManagerImpl: The class that contains routines that will add or delete db records from the port_profile table. If you want to create/delete a portprofile, call functions from this class. e. Changes to create-schema.sql to create the port_profile table. 2. Cleaned up code: a. Removed a number of unused Dao and Manager objects in CiscoNexusVSMDeviceManagerImpl. b. Removed the ListCiscoNexusVSMNetworksCmd command. c. Removed a bunch of import statements in a few files. --- api/src/com/cloud/network/PortProfile.java | 90 -------- .../ListCiscoNexusVSMNetworksCmd.java | 103 --------- .../DefaultComponentLibrary.java | 4 +- .../CiscoNexusVSMDeviceManagerImpl.java | 124 +++-------- .../cloud/network/CiscoNexusVSMDeviceVO.java | 2 - .../cloud/network/PortProfileManagerImpl.java | 140 ++++++++++++ .../src/com/cloud/network/PortProfileVO.java | 203 ++++++++++++++++++ .../com/cloud/network/dao/PortProfileDao.java | 47 ++++ .../cloud/network/dao/PortProfileDaoImpl.java | 84 ++++++++ .../network/element/CiscoNexusVSMElement.java | 26 --- .../element/CiscoNexusVSMElementService.java | 11 - setup/db/create-schema.sql | 15 ++ 12 files changed, 516 insertions(+), 333 deletions(-) delete mode 100644 api/src/com/cloud/network/PortProfile.java delete mode 100644 server/src/com/cloud/api/commands/ListCiscoNexusVSMNetworksCmd.java create mode 100644 server/src/com/cloud/network/PortProfileManagerImpl.java create mode 100644 server/src/com/cloud/network/PortProfileVO.java create mode 100644 server/src/com/cloud/network/dao/PortProfileDao.java create mode 100644 server/src/com/cloud/network/dao/PortProfileDaoImpl.java diff --git a/api/src/com/cloud/network/PortProfile.java b/api/src/com/cloud/network/PortProfile.java deleted file mode 100644 index aa712a71efb..00000000000 --- a/api/src/com/cloud/network/PortProfile.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2012 Citrix Systems, Inc. Licensed under the -// Apache License, Version 2.0 (the "License"); you may not use this -// file except in compliance with the License. Citrix Systems, Inc. -// reserves all rights not expressly granted by 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. -// -// Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.network; - -import java.util.ArrayList; -import java.util.List; - - -/** - * - * - Allocated = null - * - AccountId = null - * - DomainId = null - * - * - State = Allocated - * - AccountId = account owner. - * - DomainId = domain of the account owner. - * - Allocated = time it was allocated. - */ -// Do we need to make PortProfile an interface?!! -// And do we need to make this implement/extend -// ControlledEntity? -public class PortProfile { - - String ACL; // String is only a placeholder type, we need to make it a proper Cisco N1KV ACL type. - - List port_channel = new ArrayList(); - - int vlanId; - - int pVlanId; - - String NetFlow; // String is a placeholder!!! Replace with correct netflow type. - - String QoS; // placeholder type!! - - String RateLimiting; // placeholder type!! - - String PortSecurity; // placeholder type!! - - long portProfileId; - - long accountId; - - long domainId; - - String portProfileName; - - portProfileType portProfileType; - - public enum portProfileType { - System, - Normal - } - - - /** - * @return database id. - */ - public long getId() { - return portProfileId; - } - - public long getAllocatedToAccountId() { - return accountId; - } - - public long getAllocatedInDomainId() { - return domainId; - } - - // We'll put in other getter/setter methods for all the other fields too. - - PortProfile() { - // Do nothing for now. - // We probably need to generate a UUID for this portprofile. - return; - } - -} diff --git a/server/src/com/cloud/api/commands/ListCiscoNexusVSMNetworksCmd.java b/server/src/com/cloud/api/commands/ListCiscoNexusVSMNetworksCmd.java deleted file mode 100644 index 77edebdc35c..00000000000 --- a/server/src/com/cloud/api/commands/ListCiscoNexusVSMNetworksCmd.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.cloud.api.commands; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.log4j.Logger; - -import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd; -import com.cloud.api.BaseListCmd; -import com.cloud.api.IdentityMapper; -import com.cloud.api.Implementation; -import com.cloud.api.Parameter; -import com.cloud.api.PlugService; -import com.cloud.api.ServerApiException; -import com.cloud.api.response.ListResponse; -import com.cloud.api.response.NetworkResponse; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; -import com.cloud.network.element.CiscoNexusVSMElementService; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.network.PortProfile; - -@Implementation(responseObject=NetworkResponse.class, description="lists network that are configured on a Cisco 1000v VSM device") -public class ListCiscoNexusVSMNetworksCmd extends BaseListCmd { - - public static final Logger s_logger = Logger.getLogger(ListCiscoNexusVSMNetworksCmd.class.getName()); - private static final String s_name = "listcisconexusvsmnetworkscmdresponse"; - @PlugService CiscoNexusVSMElementService _ciscoNexusVSMService; - - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// - - @IdentityMapper(entityTableName="external_switch_management_devices") - @Parameter(name=ApiConstants.EXTERNAL_SWITCH_MGMT_DEVICE_ID, type=CommandType.LONG, required = true, description="Cisco Nexus 1000v VSM device ID") - private Long vsmDeviceId; - - ///////////////////////////////////////////////////// - /////////////////// Accessors /////////////////////// - ///////////////////////////////////////////////////// - - public Long getvsmDeviceId() { - return vsmDeviceId; - } - - ///////////////////////////////////////////////////// - /////////////// API Implementation/////////////////// - ///////////////////////////////////////////////////// - - @Override - public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { - /** - try { - // may need to change Network to something else. - List networks = _ciscoNexusVSMService.listNetworks(this); - ListResponse response = new ListResponse(); - List networkResponses = new ArrayList(); - - if (networks != null && !networks.isEmpty()) { - for (Network network : networks) { - NetworkResponse networkResponse = _responseGenerator.createNetworkResponse(network); - networkResponses.add(networkResponse); - } - } - - response.setResponses(networkResponses); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - } catch (InvalidParameterValueException invalidParamExcp) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, invalidParamExcp.getMessage()); - } catch (CloudRuntimeException runtimeExcp) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, runtimeExcp.getMessage()); - } **/ - } - - @Override - public String getCommandName() { - return s_name; - } -} diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index c43684baef2..150d7af89b6 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -74,7 +74,7 @@ import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl; import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl; import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl; import com.cloud.dc.dao.ClusterVSMMapDaoImpl; -// TODO - Import the Port Profile Device Dao as well. +import com.cloud.network.dao.PortProfileDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; import com.cloud.network.dao.IPAddressDaoImpl; @@ -324,7 +324,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("NetScalerPodDao", NetScalerPodDaoImpl.class); addDao("CiscoNexusVSMDeviceDao", CiscoNexusVSMDeviceDaoImpl.class); addDao("ClusterVSMMapDao", ClusterVSMMapDaoImpl.class); - // TODO - Also put in the Port Profile Device Dao here. + addDao("PortProfileDao", PortProfileDaoImpl.class); addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class); addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class); addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); diff --git a/server/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java b/server/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java index 53331c788fc..fd9aea1ada9 100644 --- a/server/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java +++ b/server/src/com/cloud/network/CiscoNexusVSMDeviceManagerImpl.java @@ -15,142 +15,56 @@ package com.cloud.network; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; - -import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.StartupCommand; -import com.cloud.alert.AlertManager; import com.cloud.api.ApiConstants; -import com.cloud.configuration.Config; -import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.ClusterVSMMapVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterIpAddressVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.Pod; -import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterVSMMapDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.exception.DiscoveredWithErrorException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientNetworkCapacityException; 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.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.vmware.manager.VmwareManager; -import com.cloud.network.ExternalNetworkDeviceManager.NetworkDevice; -import com.cloud.network.Network.Service; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkExternalLoadBalancerDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.rules.dao.PortForwardingRulesDao; -import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; -import com.cloud.resource.ResourceState; -import com.cloud.resource.ResourceStateAdapter; -import com.cloud.resource.ServerResource; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.dao.AccountDao; -import com.cloud.user.dao.UserStatisticsDao; -import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; +import com.cloud.network.PortProfileVO.BindingType; +import com.cloud.network.PortProfileVO.PortType; import com.cloud.network.dao.CiscoNexusVSMDeviceDao; +import com.cloud.network.dao.PortProfileDao; import com.cloud.network.resource.CiscoNexusVSM; import com.cloud.exception.ResourceInUseException; +import com.cloud.network.PortProfileManagerImpl; public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { @Inject CiscoNexusVSMDeviceDao _ciscoNexusVSMDeviceDao; - @Inject - HostDao _hostDao; - @Inject - DataCenterDao _dcDao; - @Inject - NetworkManager _networkMgr; - @Inject - NicDao _nicDao; - @Inject - AgentManager _agentMgr; - - @Inject - IPAddressDao _ipAddressDao; - @Inject - VlanDao _vlanDao; - @Inject - NetworkOfferingDao _networkOfferingDao; - @Inject - AccountDao _accountDao; - @Inject - PhysicalNetworkDao _physicalNetworkDao; - @Inject - PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; - @Inject - AccountManager _accountMgr; - @Inject - UserStatisticsDao _userStatsDao; - @Inject - NetworkDao _networkDao; - @Inject - DomainRouterDao _routerDao; - @Inject - PortForwardingRulesDao _portForwardingRulesDao; - @Inject - ConfigurationDao _configDao; - - @Inject - NetworkExternalLoadBalancerDao _networkLBDao; - @Inject - NetworkServiceMapDao _ntwkSrvcProviderDao; - @Inject - protected HostPodDao _podDao = null; - - @Inject ClusterDao _clusterDao; @Inject ClusterVSMMapDao _clusterVSMDao; @Inject ResourceManager _resourceMgr; - - @Inject VmwareManager _vmwareMgr; - @Inject AlertManager _alertMgr; - @Inject VMTemplateDao _tmpltDao; - @Inject ClusterDetailsDao _clusterDetailsDao; - + @Inject + VmwareManager _vmwareMgr; + @Inject + ClusterDetailsDao _clusterDetailsDao; @Inject HostDetailsDao _hostDetailDao; + @Inject + PortProfileDao _ppDao; + private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class); @@ -163,7 +77,6 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { // First check if the cluster is of type vmware. If not, // throw an exception. VSMs are tightly integrated with vmware clusters. - s_logger.info("in addCiscoNexuVSM, clusterId is --> " + clusterId + ", ipaddress is --> " + ipaddress + ", username --> " + username + ", pwd --> " + password + ", vcenterip --> " + vCenterIpaddr + ", vCenterdcName --> " + vCenterDcName); ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null) { @@ -346,6 +259,12 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { } } + /***** + // Ok, I'm putting in a port profile creation call here. Just for testing. + PortProfileManagerImpl obj = new PortProfileManagerImpl(); + obj.addPortProfile("pp1", 1, 4000, PortType.vEthernet, BindingType.Ephemeral); + ***/ + return true; } @@ -370,7 +289,14 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { throw new CloudRuntimeException(e.getMessage()); } } - + + /** + // Deleting the same port profile.. + PortProfileVO obj = _ppDao.findByName("pp1"); + PortProfileManagerImpl obj2 = new PortProfileManagerImpl(); + obj2.deletePortProfile(obj.getId()); + //_ppmgr.addPortProfile("pp1", 1, 4000, PortType.vEthernet, BindingType.Ephemeral); + **/ return true; } diff --git a/server/src/com/cloud/network/CiscoNexusVSMDeviceVO.java b/server/src/com/cloud/network/CiscoNexusVSMDeviceVO.java index 047f08c85e6..d05f548d80c 100644 --- a/server/src/com/cloud/network/CiscoNexusVSMDeviceVO.java +++ b/server/src/com/cloud/network/CiscoNexusVSMDeviceVO.java @@ -22,8 +22,6 @@ import java.util.UUID; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; diff --git a/server/src/com/cloud/network/PortProfileManagerImpl.java b/server/src/com/cloud/network/PortProfileManagerImpl.java new file mode 100644 index 00000000000..d5272304867 --- /dev/null +++ b/server/src/com/cloud/network/PortProfileManagerImpl.java @@ -0,0 +1,140 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.hypervisor.vmware.manager.VmwareManager; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.network.PortProfileVO.BindingType; +import com.cloud.network.PortProfileVO.PortType; +import com.cloud.network.dao.PortProfileDaoImpl; + +public class PortProfileManagerImpl { + + //@Inject + //static PortProfileDao _portProfileDao; + @Inject + VmwareManager _vmwareMgr; + + private PortProfileDaoImpl _portProfileDao; + + private static final org.apache.log4j.Logger s_logger = Logger.getLogger(PortProfileManagerImpl.class); + + public PortProfileManagerImpl() { + _portProfileDao = new PortProfileDaoImpl(); + } + + @DB + public PortProfileVO addPortProfile(String portProfName, long vsmId, int vlanId, PortType pType, BindingType bType) { + + // In this function, we create a port profile record in the port_profile table. + s_logger.info("Inside addPortProfile.. name --> " + portProfName + " vsmId --> " + vsmId + " vlan id --> " + vlanId + " pType --> " + pType + "btype --> " + bType); + // First, check if a port profile with the given name already exists. If it does, throw an exception. + + if (_portProfileDao.findByName(portProfName) != null) { + s_logger.info("Port Profile with specified name: " + portProfName + " already exists"); + throw new InvalidParameterValueException("Port Profile with specified name: " + portProfName + " already exists"); + } + s_logger.info("Ok didn't find a portprofile by name " + portProfName); + // Check if the VSM id is a valid one. + + // TODO: Should we also check whether a port profile for the specified vlanId already exists, and if so, + // fail this function? Do we want to enforce such a 1:1 mapping b/w port profile and vlanId? + + // Else, go ahead and create the port profile. + PortProfileVO portProfileObj = new PortProfileVO(portProfName, vsmId, vlanId, pType, bType); + + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + _portProfileDao.persist(portProfileObj); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + throw new CloudRuntimeException(e.getMessage()); + } + + // Return the PortProfileVO object created. + return portProfileObj; + } + + @DB + public PortProfileVO addPortProfile(String portProfName, long vsmId, int lowVlanId, int highVlanId, PortType pType, BindingType bType) { + + // In this function, we create a port profile record in the port_profile table. + + // First, check if a port profile with the given name already exists. If it does, throw an exception. + PortProfileVO portProfileObj; + + portProfileObj = _portProfileDao.findByName(portProfName); + + if (portProfileObj != null) { + s_logger.info("Port Profile with specified name: " + portProfName + " already exists"); + throw new InvalidParameterValueException("Port Profile with specified name: " + portProfName + " already exists"); + } + + // Next, check if there is any existing port profile that uses a VLAN ID range that clashes with the + // range passed to this function. If so, throw an exception. + + if (_portProfileDao.doesVlanRangeClash(lowVlanId, highVlanId) == true) { + s_logger.info("Port Profile's vlanId range clashes with an existing Port Profile's"); + throw new InvalidParameterValueException("Port Profile's vlanId range clashes with an existing Port Profile's"); + } + + // Else, go ahead and create the port profile. + portProfileObj = new PortProfileVO(portProfName, vsmId, lowVlanId, highVlanId, pType, bType); + + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + _portProfileDao.persist(portProfileObj); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + throw new CloudRuntimeException(e.getMessage()); + } + + // Return the PortProfileVO object created. + return portProfileObj; + } + + @DB + public boolean deletePortProfile(long portProfileId) { + PortProfileVO ppObj = _portProfileDao.findById(portProfileId); + if (ppObj == null) { + // This entry is already not present. Return success. + return true; + } + + //Else, remove it. + // TODO: Should we be putting any checks here before removing + // the port profile record from the db? + + Transaction txn = Transaction.currentTxn(); + try { + txn.start(); + // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. + _portProfileDao.remove(portProfileId); + txn.commit(); + } catch (Exception e) { + s_logger.info("Caught exception when trying to delete Port Profile record.." + e.getMessage()); + throw new CloudRuntimeException("Failed to delete Port Profile"); + } + return true; + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/PortProfileVO.java b/server/src/com/cloud/network/PortProfileVO.java new file mode 100644 index 00000000000..38905a3c25e --- /dev/null +++ b/server/src/com/cloud/network/PortProfileVO.java @@ -0,0 +1,203 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.network; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import com.cloud.exception.InvalidParameterValueException; + +/** + * PortProfileVO contains information on portprofiles that are created on a Cisco Nexus 1000v VSM associated + * with a VMWare cluster. + */ + +@Entity +@Table(name="port_profile") +public class PortProfileVO { + + // We need to know what properties a VSM has. Put them here. + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name = "port_profile_name") + private String portProfileName; + + @Column(name = "port_mode") + private PortMode portMode; + + @Column(name = "vsm_id") + private long vsmId; + + @Column(name = "trunk_low_vlan_id") + private int lowVlanId; + + @Column(name = "trunk_high_vlan_id") + private int highVlanId; + + @Column(name = "access_vlan_id") + private int accessVlanId; + + @Column(name = "port_type") + private PortType portType; + + @Column(name = "port_binding") + private BindingType portBinding; + + public enum BindingType { + Static, + Ephemeral + } + + public enum PortType { + Ethernet, + vEthernet + } + + // This tells us whether the port trunks multiple VLANs + // or carries traffic of a single VLAN. + public enum PortMode { + Access, + Trunk + } + + // Accessor methods + public long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + public String getPortProfileName() { + return portProfileName; + } + + public PortMode getPortMode() { + return portMode; + } + + public long getVsmId() { + return vsmId; + } + + public int getLowVlanId() { + return lowVlanId; + } + + public int getHighVlanId() { + return highVlanId; + } + + public int getAccessVlanId() { + return accessVlanId; + } + + public PortType getPortType() { + return portType; + } + + public BindingType getPortBinding() { + return portBinding; + } + + // Setter methods + + public void setPortProfileName(String name) { + portProfileName = name; + } + + public void setPortMode(PortMode mode) { + portMode = mode; + } + + public void setVsmId(long id) { + vsmId = id; + } + + public void setLowVlanId(int vlanId) { + lowVlanId = vlanId; + } + + public void setHighVlanId(int vlanId) { + highVlanId = vlanId; + } + + public void setAccessVlanId(int vlanId) { + accessVlanId = vlanId; + } + + public void setPortType(PortType type) { + portType = type; + } + + public void setPortBinding(BindingType bindingType) { + portBinding = bindingType; + } + + // Constructor methods. + + public PortProfileVO(String portProfName, long vsmId, int vlanId, PortType pType, BindingType bType) { + // Set the relevant portprofile properties here. + // When supplied with a single vlanId, we set this portprofile as an access port profile. + + this.setPortMode(PortMode.Access); + + this.uuid = UUID.randomUUID().toString(); + this.setPortProfileName(portProfName); + this.setVsmId(vsmId); + this.setAccessVlanId(vlanId); + this.setPortType(pType); + this.setPortBinding(bType); + } + + public PortProfileVO(String portProfName, long vsmId, int lowVlanId, int highVlanId, PortType pType, BindingType bType) { + // Set the relevant portprofile properties here. + // When supplied with a vlan range, we set this portprofile as a trunk port profile. + + if (lowVlanId >= highVlanId) { + throw new InvalidParameterValueException("Low Vlan Id cannot be greater than or equal to high Vlan Id"); + } + this.setPortMode(PortMode.Trunk); + + this.uuid = UUID.randomUUID().toString(); + this.setPortProfileName(portProfName); + this.setVsmId(vsmId); + this.setLowVlanId(lowVlanId); + this.setHighVlanId(highVlanId); + this.setPortType(pType); + this.setPortBinding(bType); + } + + public PortProfileVO() { + this.uuid = UUID.randomUUID().toString(); + } +} diff --git a/server/src/com/cloud/network/dao/PortProfileDao.java b/server/src/com/cloud/network/dao/PortProfileDao.java new file mode 100644 index 00000000000..32edd56547f --- /dev/null +++ b/server/src/com/cloud/network/dao/PortProfileDao.java @@ -0,0 +1,47 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.dao; + +import java.util.List; +import com.cloud.network.PortProfileVO; +import com.cloud.utils.db.GenericDao; + +public interface PortProfileDao extends GenericDao { + + /** + * Return a Port Profile VO (db record) given its name. + */ + PortProfileVO findByName(String portProfileName); + + /* + * Returns true if there already is any portprofile that trunks + * vlan IDs in a specified range. + */ + boolean doesVlanRangeClash(int lowVlanId, int highVlanId); + + /* + * Return a list of port profiles that have the specified access vlanID. + */ + List listByVlanId(int vlanId); + + /** + * Other candidate functions that could be helpful. + * + * List all portprofiles configured with a particular id. + * List listByVlanId(int vlanId); + * + * List all uplink portprofiles (these represent physical ports). + * List listAllUplinkPortProfiles(); // we may have to provide some filter, like clusterId or zoneId or something. + * + */ +} \ No newline at end of file diff --git a/server/src/com/cloud/network/dao/PortProfileDaoImpl.java b/server/src/com/cloud/network/dao/PortProfileDaoImpl.java new file mode 100644 index 00000000000..751e5bbc41b --- /dev/null +++ b/server/src/com/cloud/network/dao/PortProfileDaoImpl.java @@ -0,0 +1,84 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by 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. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.dao; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.PortProfileVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.exception.CloudRuntimeException; + +@Local(value=PortProfileDao.class) @DB(txn=false) +public class PortProfileDaoImpl extends GenericDaoBase implements PortProfileDao { + protected static final Logger s_logger = Logger.getLogger(PortProfileDaoImpl.class); + + final SearchBuilder nameSearch; + final SearchBuilder accessVlanSearch; + + public PortProfileDaoImpl() { + super(); + + nameSearch = createSearchBuilder(); + nameSearch.and("portProfileName", nameSearch.entity().getPortProfileName(), Op.EQ); + nameSearch.done(); + + accessVlanSearch = createSearchBuilder(); + accessVlanSearch.and("accessVlanId", accessVlanSearch.entity().getAccessVlanId(), Op.EQ); + accessVlanSearch.done(); + } + + public PortProfileVO findByName(String portProfileName) { + SearchCriteria sc = nameSearch.create(); + sc.setParameters("portProfileName", portProfileName); + return findOneBy(sc); + } + + @DB + public boolean doesVlanRangeClash(int lowVlanId, int highVlanId) { + String dbName = "cloud"; + String tableName = "port_profile"; + String condition = "(trunk_low_vlan_id BETWEEN " + lowVlanId + " AND " + highVlanId + ")" + " OR (trunk_high_vlan_id BETWEEN " + lowVlanId + " AND " + highVlanId + ")"; + String selectSql = "SELECT * FROM `" + dbName + "`.`" + tableName + "` WHERE " + condition; + + Transaction txn = Transaction.currentTxn(); + try { + PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); + ResultSet rs = stmt.executeQuery(); + if (rs != null && rs.next()) { + // There are records that contain vlans in this range, so return true + return true; + } + } catch (SQLException ex) { + throw new CloudRuntimeException("Failed to execute SQL query to check for vlan range clash"); + } + return false; + } + + public List listByVlanId(int vlanId) { + SearchCriteria sc = accessVlanSearch.create(); + sc.setParameters("accessVlanId", vlanId); + return search(sc, null); + } + +} \ No newline at end of file diff --git a/server/src/com/cloud/network/element/CiscoNexusVSMElement.java b/server/src/com/cloud/network/element/CiscoNexusVSMElement.java index cb4966eb23a..870691feca9 100644 --- a/server/src/com/cloud/network/element/CiscoNexusVSMElement.java +++ b/server/src/com/cloud/network/element/CiscoNexusVSMElement.java @@ -25,7 +25,6 @@ import com.cloud.api.commands.DeleteCiscoNexusVSMCmd; import com.cloud.api.commands.ListCiscoNexusVSMCmd; import com.cloud.api.commands.EnableCiscoNexusVSMCmd; import com.cloud.api.commands.DisableCiscoNexusVSMCmd; -import com.cloud.api.commands.ListCiscoNexusVSMNetworksCmd; import com.cloud.api.response.CiscoNexusVSMResponse; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; @@ -52,7 +51,6 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -import com.cloud.network.PortProfile; import com.cloud.network.element.NetworkElement; import com.cloud.offering.NetworkOffering; import com.cloud.utils.component.Manager; @@ -214,29 +212,6 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme result = disableCiscoNexusVSM(cmd.getCiscoNexusVSMDeviceId()); return result; } - - @Override - public List listNetworks(ListCiscoNexusVSMNetworksCmd cmd) { - - /*** - // Get the device id of the VSM from the database. - Long vsmDeviceId = cmd.getvsmDeviceId(); - - // Get all details of the VSM by firing a dao find (querying the db). - CiscoNexusVSMDeviceVO vsmDeviceVo = _lbDeviceDao.findById(vsmDeviceId); - - List portProfileMap = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); - if (networkLbMaps != null && !networkLbMaps.isEmpty()) { - for (NetworkExternalLoadBalancerVO networkLbMap : networkLbMaps) { - NetworkVO network = _networkDao.findById(networkLbMap.getNetworkId()); - networks.add(network); - } - } - - return networks; - ***/ - return null; - } @Override public List listCiscoNexusVSMs(ListCiscoNexusVSMCmd cmd) { @@ -244,7 +219,6 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme } - @Override public CiscoNexusVSMResponse createCiscoNexusVSMResponse(CiscoNexusVSMDeviceVO vsmDeviceVO) { CiscoNexusVSMResponse response = new CiscoNexusVSMResponse(); diff --git a/server/src/com/cloud/network/element/CiscoNexusVSMElementService.java b/server/src/com/cloud/network/element/CiscoNexusVSMElementService.java index a9b0a06e461..a9b8676c2b9 100644 --- a/server/src/com/cloud/network/element/CiscoNexusVSMElementService.java +++ b/server/src/com/cloud/network/element/CiscoNexusVSMElementService.java @@ -20,16 +20,12 @@ package com.cloud.network.element; import java.util.List; import com.cloud.api.commands.AddCiscoNexusVSMCmd; -import com.cloud.api.commands.ConfigureCiscoNexusVSMCmd; import com.cloud.api.commands.DeleteCiscoNexusVSMCmd; import com.cloud.api.commands.EnableCiscoNexusVSMCmd; import com.cloud.api.commands.DisableCiscoNexusVSMCmd; -import com.cloud.api.commands.ListCiscoNexusVSMNetworksCmd; import com.cloud.api.commands.ListCiscoNexusVSMCmd; import com.cloud.api.response.CiscoNexusVSMResponse; import com.cloud.network.CiscoNexusVSMDeviceVO; -import com.cloud.network.Network; -import com.cloud.network.PortProfile; import com.cloud.utils.component.PluggableService; public interface CiscoNexusVSMElementService extends PluggableService { @@ -55,13 +51,6 @@ public interface CiscoNexusVSMElementService extends PluggableService { */ public List listCiscoNexusVSMs(ListCiscoNexusVSMCmd cmd); - /** - * lists all the networks (port profiles) configured on the VSM. - * @param ListCiscoNexusVSMCmd - * @return list of the guest networks that are using this Netscaler load balancer - */ - public List listNetworks(ListCiscoNexusVSMNetworksCmd cmd); - /** * Enables a Cisco Nexus VSM. */ diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 08e5c949dea..286a0137cf8 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -136,6 +136,7 @@ DROP TABLE IF EXISTS `cloud`.`dc_storage_network_ip_range`; DROP TABLE IF EXISTS `cloud`.`op_dc_storage_network_ip_address`; DROP TABLE IF EXISTS `cloud`.`cluster_vsm_map`; DROP TABLE IF EXISTS `cloud`.`virtual_supervisor_module`; +DROP TABLE IF EXISTS `cloud`.`port_profile`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -2109,6 +2110,20 @@ CREATE TABLE `cloud`.`virtual_supervisor_module` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`port_profile` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `port_profile_name` varchar(255), + `port_mode` varchar(10), + `vsm_id` bigint unsigned NOT NULL, + `trunk_low_vlan_id` int, + `trunk_high_vlan_id` int, + `access_vlan_id` int, + `port_type` varchar(20) NOT NULL, + `port_binding` varchar(20), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `cloud`.`netscaler_pod_ref` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',